Created
April 27, 2020 12:47
-
-
Save EBrown8534/68d43512c14324a9fcdaf6da7ec1ead7 to your computer and use it in GitHub Desktop.
F# Monty Hall Problem Analysis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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