open Graphics ;; Random.self_init () ;; type operation = Val of int | Sum of operation * operation | Diff of operation * operation | Prod of operation * operation | Exp of operation * int ;; let rec calculate = function | Val k -> k | Exp (op, k) -> Math.pw (calculate op) k | Sum (f, g) -> (calculate f) + (calculate g) | Diff (f, g) -> (calculate f) - (calculate g) | Prod (f, g) -> (calculate f) * (calculate g) ;; let generate_random_calc ?plus_w:(pw=10) ?minus_w:(mw=8) ?prod_w:(uw=2) ?exp_w:(ew=0) (length : int) (inf : int) (sup : int) = let sum = pw + mw + uw + ew in let rec aux = function | 0 | 1 -> Val (inf + Random.int (sup - inf)) | k -> let r = Random.int sum in if r < pw then begin if Random.int 2 = 0 then Sum(aux 0, aux (k-1)) else Sum(aux (k-1), aux 0) end else if r < pw+mw then begin if Random.int 2 = 0 then Diff(aux 0, aux (k-1)) else Diff(aux (k-1), aux 0) end else if r < pw+mw+uw then begin if Random.int 2 = 0 then Prod(aux 0, aux (k-1)) else Prod(aux (k-1), aux 0) end else begin Exp(aux (k-1), 2 + Random.int 2) end in aux length ;; let draw_bracket_open ?retval:(rv=Drawing.fodder) (x : int) (y : int) (size : int) = moveto (x + size/4) (y+5*size/4) ; lineto (x) (y+size/2) ; lineto (x) (y-size/2) ; lineto (x + size/4) (y-5*size/4) ; rv := x + size/4 +6 ;; let draw_bracket_close ?retval:(rv=Drawing.fodder) (x : int) (y : int) (size : int) = moveto (x) (y+5*size/4) ; lineto (x + size/4) (y+size/2) ; lineto (x + size/4) (y-size/2) ; lineto (x) (y-5*size/4) ; rv := x + size/4 +6 ;; let draw_sign ?retval:(rv=Drawing.fodder) (x : int) (y : int) (len : int) = function | '+' -> draw_poly_line [|(x, y); (x + len, y)|] ; draw_poly_line [|(x+len/2, y + len/2); (x+len/2, y - len/2)|] ; | '-' -> draw_poly_line [|(x, y); (x + len, y)|] ; | 'x' -> Drawing.draw_letter x y 'x' len ; | _ -> failwith "incorrect\n" ;; let require_bracket = function | Val _ -> false | _ -> true ;; let print_calc (f : operation) (x0 : int) (y0 : int) (size : int) = set_line_width 3 ; set_color black ; let x = ref x0 in let rec aux = function | Val k -> Drawing.draw_integer_alignedleft !x y0 k size ~retval:x ; (*Printf.printf "%d --> \n" !x ;*) | Exp (f, k) -> () | Sum (f, g) -> if require_bracket f then draw_bracket_open !x y0 size ~retval:x ; aux f ; if require_bracket f then draw_bracket_close !x y0 size ~retval:x ; draw_sign !x y0 size '+' ~retval:x ; x := !x + size*10/7 ; if require_bracket g then draw_bracket_open !x y0 size ~retval:x ; aux g ; if require_bracket g then draw_bracket_close !x y0 size ~retval:x ; | Diff (f, g) -> if require_bracket f then draw_bracket_open !x y0 size ~retval:x ; aux f ; if require_bracket f then draw_bracket_close !x y0 size ~retval:x ; draw_sign !x y0 size '-' ~retval:x ; x := !x + size*10/7 ; if require_bracket g then draw_bracket_open !x y0 size ~retval:x ; aux g ; if require_bracket g then draw_bracket_close !x y0 size ~retval:x ; | Prod (f, g) -> if require_bracket f then draw_bracket_open !x y0 size ~retval:x ; aux f ; if require_bracket f then draw_bracket_close !x y0 size ~retval:x ; draw_sign !x y0 (size/2) 'x' ~retval:x ; x := !x + size*10/7 ; if require_bracket g then draw_bracket_open !x y0 size ~retval:x ; aux g ; if require_bracket g then draw_bracket_close !x y0 size ~retval:x ; in aux f ;; let maeth_main () = let start = Unix.gettimeofday () in let found = ref false in while not !found && (Unix.gettimeofday() -. start <= !Csts.time_to_ans_f) do () done ; if !found then begin incr Csts.combo ; true end else begin Csts.combo := 0 ; false end ;;