Imagine this probability puzzle:

  • There are three doors, with a prize behind one of them.
  • You choose a door that you think the prize is behind.
  • One of the two remaining doors gets opened and shown to be empty.
  • You now have another decision to make:
    • Stay with your original choice of door.
    • Or swap your choice of door to the other remaining closed door.

On the surface it appears the last decision should make no impact as it's just a 50/50 decision, right? You may be surprised.

In essence this is known as the Monty Hall problem and when it was originally discovered nobody believed it until simulations were done. I'm going to try it out in a PowerShell function:

function Test-MontyHall {
    param (
        [int] $MaxSimulations = 1000,
        [bool] $SwapChoice = $true
    )

    $detailLog = @()
    $winCount = 0
    $loseCount = 0
 
    for ($simulationCount = 1; $simulationCount -le $MaxSimulations; $simulationCount++) {
        # Pick a random door for the prize and your choice, both from 1..3
        $prizeDoor = (Get-Random 3) + 1
        $firstChoice = (Get-Random 3) + 1
        # Pick one of the doors left over to be shown to be empty
        $emptyDoor = (1..3 | Where { $_ -notin $firstChoice, $prizeDoor } | Select -First 1)
        
        # Stay with our first choice
        if (!$SwapChoice) {
            $secondChoice = $firstChoice
        } else {
            # Or swap our choice to the other remaining closed door
            $secondChoice = (1..3 | Where { $_ -notin $firstChoice,$emptyDoor })
        }
         
        # Evaluate the result
        if ($prizeDoor -eq $secondChoice) {
            $winCount++
        } else {
            $loseCount++       
        }

        $detailLog += [PSCustomObject] @{
            FirstChoice = $firstChoice
            EmptyDoor = $emptyDoor
            SecondChoice = $secondChoice
            PrizeDoor = $prizeDoor
        }
    }
 
    # Our final counts
    [PSCustomObject] @{
        Win = $winCount
        Lose = $loseCount
        SuccessPercentage = ("{0:P0}" -f ($winCount / $MaxSimulations))
        DetailLog = $detailLog
    }
}

I made lots of mistakes in this when I first wrote this post, so we better test it first!

Cls
$simulationCount = 1000

# Run some tests because I had a lot of bugs in the code along the way
$false, $true | %{
    Write-Host "Testing Monty Hall results ($(if ($_) { "swap choice" } else { "stay with original choice" })): " -NoNewLine

    $test = Test-MontyHall -SimulationCount $simulationCount -SwapChoice $_
    if ($test.Win -ne ($test.DetailLog | Where-Object { $_.SecondChoice -eq $_.PrizeDoor } | Measure-Object).Count) {
        Write-Error "Testing win count failed"
    }
    if ($test.DetailLog | Where-Object { $_.EmptyDoor -in $_.FirstChoice,$_.SecondChoice,$_.PrizeDoor }) {
        Write-Error "Testing empty doors failed"
    }
    if ($test.DetailLog | Where-Object { !($_.FirstChoice -is [int] -and $_.EmptyDoor -is [int] -and $_.SecondChoice -is [int] -and $_.PrizeDoor -is [int]) }) {
        Write-Error "Testing door assignment failed"
    }
    Write-Host "Ok"
}
Testing Monty Hall results (stay with original choice): Ok
Testing Monty Hall results (swap choice): Ok

Well hopefully that's all of them. And now for the simulation:

"Running Monty Hall, $simulationCount simulations, staying with original choice"
$stay = Test-MontyHall -SimulationCount $simulationCount -SwapChoice $false
$stay | Format-List
 
"Running Monty Hall, $simulationCount simulations, swapping choice"
$swap = Test-MontyHall -SimulationCount $simulationCount -SwapChoice $true
$swap | Format-List
Running Monty Hall, 1000 simulations, staying with original choice

Win               : 307
Lose              : 693
SuccessPercentage : 31%
DetailLog         : {@{FirstChoice=2; EmptyDoor=1; SecondChoice=2; PrizeDoor=2}, @{FirstChoice=3; EmptyDoor=1;
                    SecondChoice=3; PrizeDoor=2}, @{FirstChoice=3; EmptyDoor=1; SecondChoice=3; PrizeDoor=2},
                    @{FirstChoice=1; EmptyDoor=2; SecondChoice=1; PrizeDoor=3}...}

Running Monty Hall, 1000 simulations, swapping choice

Win               : 664
Lose              : 336
SuccessPercentage : 66%
DetailLog         : {@{FirstChoice=1; EmptyDoor=2; SecondChoice=3; PrizeDoor=1}, @{FirstChoice=2; EmptyDoor=1;
                    SecondChoice=3; PrizeDoor=2}, @{FirstChoice=1; EmptyDoor=2; SecondChoice=3; PrizeDoor=1},
                    @{FirstChoice=3; EmptyDoor=1; SecondChoice=2; PrizeDoor=3}...}

Your exact results will vary but you can see the two percentages stick around 33% and 66% respectively meaning if you decide to change your choice at the end you get those better odds. Your probability of being correct changes from 1 in 3 to 2 in 3. But based on the original description of the problem it's not that obvious how it makes a difference, right?