A quick script knocked up to test the theories in the Monty Hall Problem. Defaults to run 1000 tests, but this can be adjusted using the $NumberOfTests parameter.
A second parameter controls the choice of whether to switch doors, or stick with the same one. This is the $Choice parameter and can accept the following options. The default option is LetFateDecide.
- StickWithDoor
- SwitchDoor
- LetFateDecide
Examples
Runs 1000 instances of the Monty Hall Problem
./Test-MontyHallProblem.ps1
Runs 1000 instances of the Monty Hall Problem where the door gets switched every time
./Test-MontyHallProblem.ps1 -Choice 'SwitchDoor'
Runs 5000 instances of the Monty Hall Problem, sticking with the same door everytime.
./Test-MontyHallProblem.ps1 -NumberOfTests 5000 -Choice 'StickWithDoor'
Full Script – Test-MontyHallProblem.ps1
[CmdLetBinding()]
param
(
[Parameter()]
[int]$NumberOfTests = 1000,
[Parameter()]
[ValidateSet('StickWithDoor','SwitchDoor','LetFateDecide')]
[string]$Choice = 'LetFateDecide'
)
$gameShowClass = @"
public class GameShow
{
public GameShow()
{
this.Door1 = "Goat";
this.Door2 = "Goat";
this.Door3 = "Goat";
}
public string Door1 { get; set; }
public string Door2 { get; set; }
public string Door3 { get; set; }
}
"@
Add-Type -TypeDefinition $gameShowClass
$resultsClass = @"
public class GameShowResults
{
public int TestNumber { get; set; }
public string FirstChoice { get; set; }
public string DoorRemoved { get; set; }
public string FinalChoice { get; set; }
public string Decision { get; set; }
public string Prize { get; set; }
}
"@
Add-Type -TypeDefinition $resultsClass
function New-GameShow
{
$gameShow = New-Object -TypeName 'GameShow'
$prizeDoor = Get-Random -Minimum 1 -Maximum 4
switch ($prizeDoor)
{
1 { $gameShow.Door1 = "Car" }
2 { $gameShow.Door2 = "Car" }
3 { $gameShow.Door3 = "Car" }
}
Write-Output $gameShow
}
function Test-MontyHallProblem
{
param
(
[int]$TestNumber,
[string]$Choice
)
$GameShow = New-GameShow
$Results = New-Object -TypeName GameShowResults
$Results.TestNumber = $TestNumber
$PrizeDoor = 1..3 | ForEach-Object {
$Property = "Door$($_)"
if ($GameShow.$Property -eq 'Car') { $_ }
}
$FirstChoice = Get-Random -Minimum 1 -Maximum 4
$Results.FirstChoice = "Door$($FirstChoice)"
$RemainingDoors = 1..3 | Where { $_ -ne $FirstChoice }
$DoorRemoved = Get-Random -InputObject ($RemainingDoors | Where { $_ -ne $PrizeDoor })
$Results.DoorRemoved = "Door$($DoorRemoved)"
switch ($Choice)
{
'LetFateDecide'
{
$FinalChoice = Get-Random -InputObject (1..3 | Where { $_ -ne $DoorRemoved })
}
'StickWithDoor'
{
$FinalChoice = $FirstChoice
}
'SwitchDoor'
{
$FinalChoice = 1..3 | Where { $_ -ne $DoorRemoved -and $_ -ne $FirstChoice }
}
}
$Results.FinalChoice = "Door$($FinalChoice)"
if ($FirstChoice -eq $FinalChoice)
{
$Results.Decision = 'Stick'
}
else
{
$Results.Decision = 'Switch'
}
$FinalDoor = "Door$($FinalChoice)"
$Results.Prize = $GameShow.$FinalDoor
Write-Output $Results
}
Clear-Host
$ResultsArray = @()
$Counter = 1
1..$NumberOfTests | ForEach-Object {
Write-Progress -Activity 'Testing the Monty Hall Problem'
-Status "Running Test Number $($_)"
-PercentComplete (($Counter / $NumberOfTests) * 100)
$ResultsArray += Test-MontyHallProblem -TestNumber $Counter -Choice $Choice
$Counter++
}
$NumberOfSticks = ($ResultsArray | Where { $_.Decision -eq 'Stick' }).Count
$NumberOfStickWins = ($ResultsArray | Where { $_.Decision -eq 'Stick' -and $_.Prize -eq 'Car' }).Count
$NumberOfSwitches = ($ResultsArray | Where { $_.Decision -eq 'Switch' }).Count
$NumberOfSwitchWins = ($ResultsArray | Where { $_.Decision -eq 'Switch' -and $_.Prize -eq 'Car' }).Count
$global:TestResults = $null
$global:TestResults = $ResultsArray
Write-Host
Write-Host "Monty Hall Problem Tester" -ForegroundColor Yellow
Write-Host "----- ---- ------- ------" -ForegroundColor White
Write-Host
Write-Host "Number of Tests Run: " -ForegroundColor Yellow -NoNewline
Write-Host $NumberOfTests -ForegroundColor White
if ($Choice -match "(LetFateDecide|StickWithDoor)")
{
Write-Host
Write-Host "Number of Times Staying with the Same Door: " -ForegroundColor Yellow -NoNewline
Write-Host ("$($NumberOfSticks) ({0:N2} %)" -f $(($NumberOfSticks / $NumberOfTests) * 100)) -ForegroundColor White
Write-Host "Number of Times Staying with the Same Door Won the Car: " -ForegroundColor Yellow -NoNewline
if ($NumberOfStickWins)
{
Write-Host ("$($NumberOfStickWins) ({0:N2} %)" -f (($NumberOfStickWins / $NumberOfSticks) * 100)) -ForegroundColor White
}
else
{
Write-Host "$($NumberOfStickWins) (0.00 %)" -ForegroundColor White
}
}
if ($Choice -match "(LetFateDecide|SwitchDoor)")
{
Write-Host
Write-Host "Number of Times Switching Doors: " -ForegroundColor Yellow -NoNewline
Write-Host ("$($NumberOfSwitches) ({0:N2} %)" -f $(($NumberOfSwitches / $NumberOfTests) * 100)) -ForegroundColor White
Write-Host "Number of Times Switching Doors Won the Car: " -ForegroundColor Yellow -NoNewline
if ($NumberOfSwitchWins)
{
Write-Host ("$($NumberOfSwitchWins) ({0:N2} %)" -f (($NumberOfSwitchWins / $NumberOfSwitches) * 100)) -ForegroundColor White
}
else
{
Write-Host "$($NumberOfSwitchWins) (0.00 %)" -ForegroundColor White
}
}
Write-Host
Write-Host
Write-Host "To view all Test Results run the following command:" -ForegroundColor Yellow
Write-Host
Write-Host " `$TestResults | Out-GridView" -ForegroundColor White
Write-Host
Write-Host