View difference between Paste ID: XhPabW2g and SpfB0jZX
SHOW: | | - or go back to the newest paste.
1-
type pure =
1+
module Op = struct
2-
	| Binary of expression * Ops.t * expression
2+
  type t =
3-
	| Atom of int
3+
    | Plus
4-
	and bracketed = pure
4+
    | Minus
5-
	and expression =
5+
    | Mult
6-
	| Bracketed of bracketed
6+
    | Div
7-
	| Pure of pure
7+
  [@@deriving enumerate]
8
end
9
;;
10-
type pure = Binary of expression * Ops.t * expression | Atom of int
10+
11-
and bracketed = pure
11+
type node = 
12-
and expression = Bracketed of bracketed | Pure of pure
12+
  { left : expression
13
  ; right : expression
14-
let rec enum' i =
14+
  ; op : Op.t
15-
if i = 0 then [(Atom 0)]
15+
  ; is_bracketed : bool
16-
else (
16+
  }
17-
  let children = enum (i - 1) in
17+
and expression =
18-
  List.cartesian_product children children |> List.map ~f:(fun (child1, child2) ->
18+
  | Node of node
19-
    List.concat_map Ops.all ~f:(fun op ->
19+
  | Leaf of int
20-
      [(Binary (child1, op, child2))]
20+
21-
))) |> List.concat
21+
22-
and enum i = let children = enum' i in
22+
(* enum functions to generate all possible expression of depth i *)
23-
[List.map children ~f:(fun child -> Pure(child));
23+
let rec enum i = 
24-
List.map children ~f:(fun child -> Bracketed(child))
24+
  if i = 0 then [(Leaf 0)]
25-
] |> List.concat
25+
  else (
26
    let possible_children = enum (i - 1) in
27-
let ops_to_str = function
27+
    List.bind possible_children ~f:(fun left ->
28-
| Ops.Plus -> "+"
28+
      List.bind possible_children ~f:(fun right ->
29-
| Minus -> "-"
29+
        List.bind Op.all ~f:(fun op ->
30-
| Mult -> "*"
30+
          List.bind Bool.all ~f:(fun is_bracketed ->
31-
| Div -> "/"
31+
          [Node { left; right; op; is_bracketed }])))))
32
;;
33-
let rec pure_to_str = function
33+
34-
| Binary (e1, op, e2) -> (expr_to_str e1) ^ (ops_to_str op) ^ (expr_to_str e2)
34+
(* to_str functions *)
35-
| Atom x -> Int.to_string x
35+
let op_to_str = function
36-
and bracket_to_str e = "(" ^ (pure_to_str e) ^ ")"
36+
  | Op.Plus -> "+"
37-
and expr_to_str = function
37+
  | Minus -> "-"
38-
| Bracketed x-> bracket_to_str x
38+
  | Mult -> "*"
39-
| Pure x -> pure_to_str x
39+
  | Div -> "/"
40
;;
41-
enum 2 |> List.map ~f:expr_to_str;;
41+
42
let rec expression_to_str = function
43-
["0+0+0+0"; "0+0-0+0"; "0+0*0+0"; "0+0/0+0"; "0+0+0-0"; "0+0-0-0"; "0+0*0-0";
43+
  | Leaf x -> Int.to_string x
44-
 "0+0/0-0"; "0+0+0*0"; "0+0-0*0"; "0+0*0*0"; "0+0/0*0"; "0+0+0/0"; "0+0-0/0";
44+
  | Node { left; right; op; is_bracketed } -> 
45-
 "0+0*0/0"; "0+0/0/0"; "0+0+0+(0)"; "0+0-0+(0)"; "0+0*0+(0)"; "0+0/0+(0)"; ...
45+
    let inside = (expression_to_str left) ^ (op_to_str op) ^ (expression_to_str right) in
46
    if is_bracketed then
47
      "(" ^ inside ^ ")"
48
    else inside
49
;;
50
  
51
(* finally running *)
52
utop # enum 2 |> List.map ~f:expression_to_str;;
53
- : string list =
54
["0+0+0+0"; "(0+0+0+0)"; "0+0-0+0"; "(0+0-0+0)"; "0+0*0+0"; "(0+0*0+0)";
55
 "0+0/0+0"; "(0+0/0+0)"; "0+0+(0+0)"; "(0+0+(0+0))"; "0+0-(0+0)";
56
 "(0+0-(0+0))"; "0+0*(0+0)"; "(0+0*(0+0))"; "0+0/(0+0)"; "(0+0/(0+0))";
57
 "0+0+0-0"; "(0+0+0-0)"; "0+0-0-0"; "(0+0-0-0)"; "0+0*0-0"; "(0+0*0-0)";
58
 "0+0/0-0"; "(0+0/0-0)"; "0+0+(0-0)"; "(0+0+(0-0))"; "0+0-(0-0)";
59
 "(0+0-(0-0))"; "0+0*(0-0)"; "(0+0*(0-0))"; "0+0/(0-0)"; "(0+0/(0-0))";
60
 "0+0+0*0"; "(0+0+0*0)"; "0+0-0*0"; "(0+0-0*0)"; "0+0*0*0"; "(0+0*0*0)";
61
 "0+0/0*0"; "(0+0/0*0)"; "0+0+(0*0)"; "(0+0+(0*0))"; "0+0-(0*0)"; ...