4 people like it.
Like the snippet!
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
More information