DEV Community

White Oak Intelligence
White Oak Intelligence

Posted on • Originally published at whiteoakintel.com on

The Monty Hall Problem: Why Switching Doors Wins 2/3 of the Time

You pick one of three doors. The host — who knows what's behind every door — opens a different door to reveal a goat, then offers you the chance to switch. Should you switch or stay?

The near-universal wrong answer is 50/50. The correct answer: switching wins with probability 2/3. Staying wins with probability 1/3. This has been verified analytically, computationally, and empirically millions of times. When Marilyn vos Savant published the correct solution in 1990, she received thousands of letters from PhD mathematicians insisting she was wrong. She was not.

The Case Enumeration

Without loss of generality, assume the car is behind Door 1. There are three equally probable initial picks:

Case 1: You pick Door 1 (car). P = 1/3.  Switch → LOSE. Stay → WIN.
Case 2: You pick Door 2 (goat). P = 1/3. Switch → WIN.  Stay → LOSE.
Case 3: You pick Door 3 (goat). P = 1/3. Switch → WIN.  Stay → LOSE.

Switch wins in 2 of 3 cases → P(win | switch) = 2/3
Stay wins in 1 of 3 cases  → P(win | stay)   = 1/3

The Bayesian Derivation

Suppose you pick Door 1 and the host opens Door 3. Applying Bayes' Theorem:

P(car at Door 1 | host opens Door 3) = (1/2 × 1/3) / (1/2) = 1/3
P(car at Door 2 | host opens Door 3) = (1   × 1/3) / (1/2) = 2/3

The host's action is not random — he always reveals a goat and never opens your door. That constrained action transfers probability mass from the opened door onto the remaining unchosen door. Switching captures that mass; staying forfeits it.

The Generalized N-Door Result

With N doors, after the host opens N−2 goat doors:

P(win | switch) = (N−1) / N
P(win | stay)   = 1 / N

At N=1000: switching wins 999/1000 of the time.

Python Simulation (1,000,000 Trials)

import random

def monty_hall_trial(switch=True):
    doors = [0, 1, 2]
    car = random.choice(doors)
    pick = random.choice(doors)
    goat_doors = [d for d in doors if d != pick and d != car]
    host_opens = random.choice(goat_doors)
    if switch:
        final = [d for d in doors if d != pick and d != host_opens][0]
    else:
        final = pick
    return final == car

n = 1_000_000
switch_rate = sum(monty_hall_trial(True)  for _ in range(n)) / n
stay_rate   = sum(monty_hall_trial(False) for _ in range(n)) / n
print(f"Switch: {switch_rate:.4f}  (exact: 0.6667)")
print(f"Stay:   {stay_rate:.4f}  (exact: 0.3333)")

Read the full article with complete Bayesian derivation and N-door generalization →

Top comments (0)