+ type t = One | Two | Three

+ val reveal_goat : t -> guess:t -> t

+ type t = One | Two | Three

+ match Random.int 3 with

+ let reveal_goat t ~guess =

+ let goat = create () in

+ if goat <> t && goat <> guess then goat

+let flip a b = if Random.bool () then a else b

+let change_guess ~guess ~goat =

+ match (guess,goat) with

+ | D.One,D.One -> flip D.Two D.Three

+ | D.Two,D.Two -> flip D.One D.Three

+ | D.Three,D.Three -> flip D.One D.Two

+ | D.One,D.Two | D.Two,D.One-> D.Three

+ | D.Two,D.Three | D.Three,D.Two -> D.One

+ | D.One,D.Three | D.Three,D.One -> D.Two

+ let door = Door.create () in

+ let guess = Door.guess () in

+ let goat = Door.reveal_goat door ~guess in

+ let new_guess = change_guess ~guess ~goat in

+ if new_guess = door then true else false

+ let door = Door.create () in

+ let guess = Door.guess () in

+ let _goat = Door.reveal_goat door ~guess in

+ if guess = door then true else false

+ if n >= trials then acc

+ else loop (f () :: acc) (n + 1)

+let win_percent trial_results =

+ let wins = List.length (List.filter trial_results ~f:(fun r -> r = true)) in

+ float wins /. float (List.length trial_results) *. 100.

+ let trials = 1000000 in

+ let switch_trials = monte trials switch in

+ let no_switch_trials = monte trials no_switch in

+ printf "switch: %f, no_switch: %f\n"

+ (win_percent switch_trials) (win_percent no_switch_trials)