Skip to content

Instantly share code, notes, and snippets.

@EBrown8534
Created April 27, 2020 12:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EBrown8534/68d43512c14324a9fcdaf6da7ec1ead7 to your computer and use it in GitHub Desktop.
Save EBrown8534/68d43512c14324a9fcdaf6da7ec1ead7 to your computer and use it in GitHub Desktop.
F# Monty Hall Problem Analysis
namespace FSharp_Analysis
module MontyHall =
open System
let next max (rand : Random) =
rand.Next(max)
let generateAnswers rand options =
Array.map (fun _ -> rand |> next options)
let groupAnalysis totalAnswers =
Array.groupBy id
>> Array.map (fun (group, items) ->
group, (items |> Array.length |> float) / (totalAnswers |> float))
>> Array.sortBy fst
let simulate rand switch answer =
// Example answer: 2
let options = [|0; 1; 2|]
// Losers are all options except the answer
// Example losers: 0; 1
let losers = options |> Array.except [|answer|]
// Example selection: 1
let selection = rand |> next 3
// Remove the user selection from the losers (the host would never open the winner)
// Example mhSelections: 0
let mhSelections = losers |> Array.except [|selection|]
// Open a random mhSelection door
// Example leftover: 1; 2
let leftover = options |> Array.except ([|mhSelections.[rand |> next mhSelections.Length]|])
// If the user is switching, pick the other leftover
// Example selection if switch: 2
// Example selection if not switch: 1
let selection = if switch then leftover |> Array.except [|selection|] |> Array.head else selection
// Example return if switch: true
// Example return if not switch: false
selection = answer
let evaluate totalAnswers =
let rand = Random()
let montyHallAnswers = generateAnswers rand 3 [|1..totalAnswers|]
let run switch = Array.map (simulate rand switch) >> groupAnalysis totalAnswers
let printStats title items =
let getResult res = Array.find (fst >> (=) res) >> snd >> (*) 100.
sprintf "%s: win %f%% / lose %f%%" title (items |> getResult true) (items |> getResult false)
let stick = montyHallAnswers |> run false
let switch = montyHallAnswers |> run true
printStats "Stick" stick, printStats "Switch" switch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment