4 people like it.

# A Monty Hall problem simulator

I'm bad at math and writing this code down helped me to understand what's up with this counter intuitive problem.

 ``` 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: ``` ``````// https://en.wikipedia.org/wiki/Monty_Hall_problem type Door = Door of int let rng = System.Random () let play (prize: Door) (pick: Door) (strategy: Door -> Door -> Door) = let remaining = if pick = prize then [ Door 1 ; Door 2 ; Door 3 ] |> List.except [pick] |> List.item (rng.Next 2) else prize (strategy pick remaining) = prize let test strategy number = let randomDoor () = rng.Next 3 + 1 |> Door let wins = [ 1 .. number ] |> List.filter (fun _ -> play (randomDoor ()) (randomDoor ()) strategy) |> List.length float wins / float number * 100.0 test (fun first _ -> first) 1000 |> printfn "Keep first door : %.2f%% success" test (fun _ other -> other) 1000 |> printfn "Switch door : %.2f%% success" test (fun first other -> if rng.Next 2 = 0 then first else other) 1000 |> printfn "Choose randomly : %.2f%% success" // example output : // Keep first door : 33.60% success // Switch door : 66.80% success // Choose randomly : 49.30% success ``````
Multiple items
union case Door.Door: int -> Door

--------------------
type Door = | Door of int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
val rng : System.Random
namespace System
Multiple items
type Random =
new : unit -> Random + 1 overload
member Next : unit -> int + 2 overloads
member NextBytes : buffer:byte[] -> unit + 1 overload
member NextDouble : unit -> float

--------------------
System.Random() : System.Random
System.Random(Seed: int) : System.Random
val play : prize:Door -> pick:Door -> strategy:(Door -> Door -> Door) -> bool
val prize : Door
val pick : Door
val strategy : (Door -> Door -> Door)
val remaining : Door
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member GetReverseIndex : rank:int * offset:int -> int
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
...
val except : itemsToExclude:seq<'T> -> list:'T list -> 'T list (requires equality)
val item : index:int -> list:'T list -> 'T
System.Random.Next() : int
System.Random.Next(maxValue: int) : int
System.Random.Next(minValue: int, maxValue: int) : int
val test : strategy:(Door -> Door -> Door) -> number:int -> float
val number : int
val randomDoor : (unit -> Door)
val wins : int
val filter : predicate:('T -> bool) -> list:'T list -> 'T list
val length : list:'T list -> int
Multiple items
val float : value:'T -> float (requires member op_Explicit)

--------------------
type float = System.Double

--------------------
type float<'Measure> = float
val first : Door
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
val other : Door