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)"; ... |