class / monty.ml

open Core.Std

module Door : sig
  type t = One | Two | Three
  
  val create : unit -> t
  val reveal_goat : t -> guess:t -> t
  val guess : unit -> t
end = struct
  Random.self_init ();;

  type t = One | Two | Three

  let create () =
    match Random.int 3 with
    | 0 -> One
    | 1 -> Two
    | 2 -> Three
    | _ -> assert false
  ;;

  let reveal_goat t ~guess =
    let rec loop () =
      let goat = create () in
      if goat <> t && goat <> guess then goat
      else loop ()
    in
    loop ()
  ;;

  let guess = create
end

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

let change_guess ~guess ~goat =
  let module D = Door in
  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 switch () =
  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 no_switch () =
  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
;;

let monte trials f =
  let rec loop acc n =
    if n >= trials then acc
    else loop (f () :: acc) (n + 1)
  in
  loop [] 0
;;

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 main () =
  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)
;;

let () = main ()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.