135 lines
4.0 KiB
OCaml
135 lines
4.0 KiB
OCaml
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 ;; |