let range min max = List.init (max + 1 - min) (fun x -> min + x)
let pow b e = int_of_float (float_of_int b ** float_of_int e)
let pi points =
let rec calc a c =
if c <= 0
then a
else (
let x = Random.float 1.0 ** 2.0 in
let y = Random.float 1.0 ** 2.0 in
let r = if x +. y <= 1.0 then 1.0 else 0.0 in
calc (a +. r) (c - 1))
in
let n = calc 0.0 points in
4.0 *. n /. float_of_int points
;;
let points = ref 10
let report = ref false
let args_parse =
let opts = [ "-p", Arg.Set_int points, ": points"; "-r", Arg.Set report, ": report" ] in
let usage = "pigreco\nusage: " ^ Sys.argv.(0) ^ " [-p points]" ^ " [-r report]" in
let anons _ = () in
Arg.parse opts anons usage
;;
let () =
Random.self_init ();
if !report
then (
let rows = range 1 6 in
let columns = range 1 3 in
let open List in
let columns' points = fold_left (fun acc _ -> pi points :: acc) [] columns |> rev in
let rows' =
fold_left
(fun acc r ->
let n = int_of_float (float_of_int !points *. (10.0 ** float_of_int r)) in
columns' n :: acc)
[]
rows
|> rev
in
iteri
(fun i r ->
let values = map (fun v -> Printf.sprintf "%f" v) r in
let values' = String.concat " | " values in
Printf.printf "points: %#12d | %s\n" (!points * (pow 10 (i + 1))) values')
rows')
else (
let pi_m = pi !points in
Printf.printf "Points: %d\nPi: %f\n" !points pi_m)
;;
➜ ./pigreco -r
points: 100 | 2.840000 | 3.240000 | 3.280000
points: 1_000 | 3.116000 | 3.116000 | 3.176000
points: 10_000 | 3.177200 | 3.132800 | 3.137600
points: 100_000 | 3.144560 | 3.153800 | 3.147280
points: 1_000_000 | 3.142216 | 3.141920 | 3.142404
points: 10_000_000 | 3.141078 | 3.140760 | 3.142664


