Advertisement
Guest User

Enumeration of integer expressions which only contains 8s

a guest
Sep 28th, 2013
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.     if count < c then
  36.     begin
  37.       let f (exp',count',value') =
  38.         enum (Add (exp, exp')) (count + count') (value + value') ;
  39.         enum (Sub (exp, exp')) (count + count') (value - value') ;
  40.         enum (Sub (exp', exp)) (count + count') (value' - value) ;
  41.         enum (Mul (exp, exp')) (count + count') (value * value') ;
  42.         if value mod value' = 0 then
  43.           enum (Div (exp, exp')) (count + count') (value / value') ;
  44.         if value' mod value = 0 then
  45.           enum (Div (exp', exp)) (count + count') (value' / value) ;            
  46.       in
  47.       List.iter f !expressions
  48.     end ;
  49.  
  50.     let froot = sqrt (float_of_int value) in
  51.     let iroot = int_of_float froot in
  52.     if float_of_int iroot = froot then
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement