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 IReadOnlyList<'T>
    interface IReadOnlyCollection<'T>
    interface IEnumerable
    interface IEnumerable<'T>
    member GetReverseIndex : rank:int * offset:int -> int
    member GetSlice : startIndex:int option * endIndex:int option -> 'T list
    member Head : 'T
    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
Raw view Test code New version

More information

Link:http://fssnip.net/81e
Posted:5 months ago
Author:Julien Di Lenarda
Tags: game , monty hall