View difference between Paste ID: ZYqTP53y and TD3w1eRq
SHOW: | | - or go back to the newest paste.
1
open Printf
2
3
type exp =
4
| Impossible
5
| Eight
6
| Add of exp * exp
7
| Sub of exp * exp
8
| Div of exp * exp
9
| Mul of exp * exp
10
| Sqrt of exp
11
12
let rec print out = function
13
| Impossible -> ()
14
| Eight -> fprintf out "8"
15
| Add (a,b) -> fprintf out "(%a + %a)" print a print b
16
| Sub (a,b) -> fprintf out "(%a - %a)" print a print b
17
| Div (a,b) -> fprintf out "(%a / %a)" print a print b
18
| Mul (a,b) -> fprintf out "(%a * %a)" print a print b
19
| Sqrt (a) -> fprintf out "sqrt(%a)" print a
20
21
let n = 256
22
let c = 4
23
24
let mem = Array.init c (fun _ -> Array.make n Impossible)
25
let expressions = ref []
26
27
let rec enum exp count value =
28
  if value > 0 && value <= n &&
29
     count > 0 && count <= c &&
30
     mem.(count-1).(value-1) = Impossible then
31
  begin
32
    mem.(count-1).(value-1) <- exp ;
33
    expressions := (exp,count,value) :: !expressions ;
34
35-
      for i = 0 to c-1 do
35+
36-
        for j = 0 to n-1 do
36+
37-
          let exp' = mem.(i).(j)
37+
      let f (exp',count',value') =
38-
          and count' = i+1
38+
        enum (Add (exp, exp')) (count + count') (value + value') ;
39-
          and value' = j+1 in
39+
        enum (Sub (exp, exp')) (count + count') (value - value') ;
40-
          if exp' <> Impossible then
40+
        enum (Sub (exp', exp)) (count + count') (value' - value) ;
41-
          begin
41+
        enum (Mul (exp, exp')) (count + count') (value * value') ;
42-
            enum (Add (exp, exp')) (count + count') (value + value') ;
42+
        if value mod value' = 0 then
43-
            enum (Sub (exp, exp')) (count + count') (value - value') ;
43+
          enum (Div (exp, exp')) (count + count') (value / value') ;
44-
            enum (Sub (exp', exp)) (count + count') (value' - value) ;
44+
        if value' mod value = 0 then
45-
            enum (Mul (exp, exp')) (count + count') (value * value') ;
45+
          enum (Div (exp', exp)) (count + count') (value' / value) ;            
46-
            if value mod value' = 0 then
46+
      in
47-
              enum (Div (exp, exp')) (count + count') (value / value') ;
47+
      List.iter f !expressions
48-
            if value' mod value = 0 then
48+
49-
              enum (Div (exp', exp)) (count + count') (value' / value) ;            
49+
50-
          end
50+
51-
        done
51+
52-
      done
52+
53
      enum (Sqrt exp) count iroot ;
54
  end
55
56
let _ =
57
  enum Eight 1 8 ;
58
  for j = 0 to 29 do
59
    printf "%d: %a\n" (j+1) print mem.(c-1).(j) ;
60
  done