Monocurl Essays
Series Download

Monty Hall problem: why switching wins two times in three

Three doors, one car, and a host who opens a goat door. Switching wins 2/3 of the time. Three solutions, and why the answer depends on what the host knows.

21 min·High school and early college·

AssumesWhat probability means: counting equally likely outcomesBayes' rule: why a positive test is usually a false alarm

The Monty Hall game, and a simulation of 1000 plays of it. You pick door 1, the host, who knows where the car is and never reveals it, opens door 3 to show a goat, and you may switch to door 2. In the simulation, staying with the first pick wins about a third of the games and switching wins about two thirds.
Monocurl source
let NG = 1000
var acc = [0]
var stay = 0
for (i in range(1, NG + 1)) {
    stay = stay + (pick3(i, 1) == pick3(i, 2))
    acc .= stay
}
let STAY = acc
let DW = 1.08
let DH = 2.5
let DY = 0.3
let dx = |d| -3.05 + d * 1.22
let BASE = -1.4
let SC = 3.0 / 800
let Tally = |g| {
    let n = to_int(floor(g + 0.001))
    let a = STAY[n]
    let b = n - a
    return [
        Box([1.55, BASE + max(a * SC, 0.02) / 2, 0], [0.85, max(a * SC, 0.02)], EMBER, 0.35, 3),
        Box([2.85, BASE + max(b * SC, 0.02) / 2, 0], [0.85, max(b * SC, 0.02)], LEAF, 0.35, 3),
        center{[1.55, BASE + a * SC + 0.3, 0]} scale{1.2} color{EMBER} Number(a, 0),
        center{[2.85, BASE + b * SC + 0.3, 0]} scale{1.2} color{LEAF} Number(b, 0),
        center{[2.95, 1.85, 0]} scale{1.15} color{INK} Number(n, 0)
    ]
}
# s from 0 to 3: you pick door 1, the host opens door 3, the offer to switch appears
let Door = |d, fillc, edge| center{[dx(d), DY, 0]} fill{fillc} stroke{edge, 4} Rect([DW, DH])
let Doors = |s| {
    let a = sm(s)
    let b = sm(s - 1)
    let c = sm(s - 2)
    let shut = tint(SLATE, 0.22)
    return [
        Door(0, lerp(shut, tint(AZURE, 0.3), a), lerp(SLATE, AZURE, a)),
        Pt([dx(0) + 0.34, DY, 0], lerp(SLATE, AZURE, a), 0.07),
        center{[dx(0), DY + 0.75, 0]} Math("1", 1.3, lerp(SLATE, AZURE, a)),
        Door(1, shut, SLATE),
        Pt([dx(1) + 0.34, DY, 0], SLATE, 0.07),
        center{[dx(1), DY + 0.75, 0]} Math("2", 1.3, SLATE),
        Door(2, lerp(shut, tint(PLUM, 0.04), b), lerp(SLATE, PLUM, b)),
        Pt([dx(2) + 0.34, DY, 0], alpha{1 - b} SLATE, 0.07),
        center{[dx(2), DY + 0.75, 0]} Math("3", 1.3, lerp(SLATE, PLUM, b)),
        center{[dx(2), DY - 0.3, 0]} Cap("goat", 0.9, alpha{b} PLUM),
        center{[dx(0), DY - DH / 2 - 0.32, 0]} Cap("your pick", 0.8, alpha{a} AZURE),
        center{[dx(1), DY - DH / 2 - 0.32, 0]} Cap("switch?", 0.8, alpha{c} INK),
        center{[dx(2), DY - DH / 2 - 0.32, 0]} Cap("opened", 0.8, alpha{b} PLUM)
    ]
}
mesh doors = Doors(s: 0)
mesh scaffold = [
    Seg([0.85, BASE, 0], [3.55, BASE, 0], SLATE, 2.5),
    center{[1.55, BASE - 0.32, 0]} Cap("stay wins", 0.76, EMBER),
    center{[2.85, BASE - 0.32, 0]} Cap("switch wins", 0.76, LEAF),
    center{[1.65, 1.85, 0]} Cap("simulation: games", 0.76, SLATE)
]
mesh tally = Tally(g: 0)

slide "play"
    play Wait(0.4)
    doors.s = 1
    play Lerp(0.7, [&doors], linear)
    doors.s = 2
    play Lerp(0.8, [&doors], linear)
    doors.s = 3
    play Lerp(0.6, [&doors], linear)
    tally.g = NG
    play Lerp(6, [&tally], linear)
    play Wait(2)

Uses the shared definitions for this lesson's figures.

You are on a game show, facing three closed doors. Behind one is a car, and behind the other two are goats. You pick a door, say door 1. The host, who knows where the car is, opens one of the other two doors, say door 3, and shows you a goat. Then he makes an offer: you may stay with door 1 or switch to door 2. Does it matter what you do?

Pause and try

Decide before reading on: is the car more likely behind door 1, more likely behind door 2, or equally likely behind either? Write down a probability for each.

Show answerHide answer

Most people say the two closed doors are equally likely, $\frac12$ each, so the offer is worthless. Under the rules stated below, door 1 has probability $\frac13$ and door 2 has probability $\frac23$. Switching doubles your chance of winning.

The puzzle is named after Monty Hall, the host of the American show Let’s Make a Deal. It became notorious in 1990, when the columnist Marilyn vos Savant gave the answer $\frac23$ in Parade magazine and received thousands of letters, many from readers with doctorates, telling her she was wrong. She was right. The simulation above plays the game 1000 times and agrees with her: staying won 334 games and switching won 666. By the law of large numbers, shares over that many games sit close to the probabilities.

An answer this counterintuitive deserves more than one argument. We will solve the problem three ways, and then change one detail of the story and watch the answer change to $\frac12$, which shows what the correct argument depends on.

The rules of the game

The answer depends on how the host behaves, so the first job is to say exactly what we assume. Informal tellings usually leave this out, and that omission is responsible for much of the arguing.

Rule 3 is the heart of it: the host is not exploring. He cannot open your door and he cannot reveal the car. Rule 4 only matters for one of our three arguments, and we will see what happens when it is dropped.

First solution: list the cases

Suppose you pick door 1. (The doors are only labels, so nothing is lost.) By rule 1 there are three equally likely cases for where the car is, and in each of them we can follow what the host must do and how each strategy fares.

  1. You pick door 1. The car is behind door 1, 2 or 3 with probability 1/3 each: three rows, one per case.
  2. The host opens a goat door that is not yours. If the car is behind door 2 or door 3 he has only one door he can open.
  3. If you stay with door 1, you win only in the first row.
  4. If you switch to the other closed door, you win in the second and third rows: two cases out of three.
The three equally likely cases when you pick door 1. In each row the host opens a goat door that is not yours. Staying wins only in the row where the car was behind door 1, and switching wins in the other two rows.
Monocurl source
let colx = |d| -3.0 + d * 1.15
let ry = |r| 0.7 - r * 1.08
let SIZE = [1.02, 0.72]
mesh head = [
    center{[colx(0), 1.72, 0]} Cap("door 1", 0.78, AZURE),
    center{[colx(0), 1.38, 0]} Cap("(yours)", 0.72, AZURE),
    center{[colx(1), 1.72, 0]} Cap("door 2", 0.78, INK),
    center{[colx(2), 1.72, 0]} Cap("door 3", 0.78, INK)
]
mesh cells = map(range(0, 3), |r| map(range(0, 3), |d| Behind([colx(d), ry(r), 0], d == r, SIZE)))
mesh opened = []
mesh hostcol = []
mesh staycol = []
mesh switchcol = []

slide "You pick door 1. The car is behind door 1, 2 or 3 with probability 1/3 each: three rows, one per case."
    play Fade(0.7)

slide "The host opens a goat door that is not yours. If the car is behind door 2 or door 3 he has only one door he can open."
    opened = [
        Mark([colx(1), ry(0), 0], PLUM, SIZE, 2.5), Mark([colx(2), ry(0), 0], PLUM, SIZE, 2.5),
        Mark([colx(2), ry(1), 0], PLUM, SIZE), Mark([colx(1), ry(2), 0], PLUM, SIZE)
    ]
    hostcol = [
        center{[1.05, 1.72, 0]} Cap("host opens", 0.76, PLUM),
        center{[1.05, ry(0), 0]} Cap("2 or 3", 0.78, PLUM),
        center{[1.05, ry(1), 0]} Cap("3", 0.82, PLUM),
        center{[1.05, ry(2), 0]} Cap("2", 0.82, PLUM)
    ]
    play Fade(0.7)

slide "If you stay with door 1, you win only in the first row."
    staycol = [
        center{[2.25, 1.72, 0]} Cap("stay", 0.78, INK),
        Verdict([2.25, ry(0), 0], 1), Verdict([2.25, ry(1), 0], 0), Verdict([2.25, ry(2), 0], 0)
    ]
    play Fade(0.6)

slide "If you switch to the other closed door, you win in the second and third rows: two cases out of three."
    switchcol = [
        center{[3.2, 1.72, 0]} Cap("switch", 0.78, INK),
        Verdict([3.2, ry(0), 0], 0), Verdict([3.2, ry(1), 0], 1), Verdict([3.2, ry(2), 0], 1)
    ]
    play Fade(0.6)

Uses the shared definitions for this lesson's figures.

Staying wins in one case out of three and switching wins in two. The table also shows why, in a form worth saying aloud. If your first pick was the car, switching loses. If your first pick was a goat, the host is forced to open the only other goat door, so the door he leaves closed is the car, and switching wins. Your first pick is a goat with probability $\frac23$.

The $\frac12$ answer comes from counting closed doors: two remain, so each gets half. But “there are two possibilities” does not make them equally likely. As the lesson on sample spaces stressed, dividing by the number of outcomes is only valid when the outcomes are equally likely, and here the two doors have very different histories. Door 1 is closed because you chose it. Door 2 is closed because the host, who knows where the car is, passed over it.

Second solution: Bayes’ theorem

A careful reader may object to the table. It shows that the strategy of switching wins two games in three overall. But at the moment of decision you know more: you saw the host open door 3 in particular. The first row of the table mixes games where he opens door 2 with games where he opens door 3. Is the chance still $\frac23$ given exactly what you saw?

This is a question about conditional probability, and the tool for it is Bayes’ theorem from the lesson on conditional probability. To restate what we need: $P(A \mid B) = P(A \cap B)/P(B)$ is the probability of $A$ given that $B$ occurred. If $B_1, \dots, B_n$ are events of positive probability, exactly one of which occurs, and $A$ is an event with $P(A) > 0$, then

$$ P(B_j \mid A) = \frac{P(A \mid B_j)\,P(B_j)}{\sum_{i=1}^{n} P(A \mid B_i)\,P(B_i)}. $$

Here the hypotheses are $C_1$, $C_2$, $C_3$: the car is behind door 1, 2 or 3. You picked door 1. The evidence is the event $E$: the host opens door 3.

Pause and try

Using the four rules, find $P(E \mid C_1)$, $P(E \mid C_2)$ and $P(E \mid C_3)$: the probability that the host opens door 3 in each of the three cases. Then apply Bayes’ theorem to get $P(C_2 \mid E)$.

Show answerHide answer

If the car is behind door 1, both other doors hide goats and by rule 4 the host opens door 3 with probability $\frac12$. If the car is behind door 2, door 3 is the only door he may open: probability 1. If the car is behind door 3 he cannot open it: probability 0. So

$$ P(C_2 \mid E) = \frac{1 \cdot \frac13}{\frac12 \cdot \frac13 + 1 \cdot \frac13 + 0 \cdot \frac13} = \frac{1/3}{1/2} = \frac23. $$
  1. You pick door 1. The car is behind each door with probability 1/3, so the square is cut into three equal columns.
  2. Divide each column by what the host does. Car at 1: he opens door 2 or 3, half each. Car at 2: he must open 3. Car at 3: he must open 2.
  3. He opened door 3, so only the purple regions remain. The car-at-2 region is twice the car-at-1 region.
Bayes’ theorem for the Monty Hall game as areas in a unit square, after you pick door 1. The columns are the three places the car can be. Each column is divided according to which door the host opens. Conditioning on “the host opens door 3” keeps the two purple regions, whose areas are 1/6 and 1/3.
Monocurl source
let X0 = -3.45
let Y0 = -1.8
let W = 3.4
let cx = |k| X0 + W * k / 3
let mid = |k| X0 + W * (k + 0.5) / 3
mesh cols = [
    Region(Rc(cx(0), cx(1), Y0, Y0 + W), tint(SLATE, 0.1)),
    Region(Rc(cx(1), cx(2), Y0, Y0 + W), tint(SLATE, 0.1)),
    Region(Rc(cx(2), cx(3), Y0, Y0 + W), tint(SLATE, 0.1))
]
mesh split = []
mesh lines = [
    Outline(Rc(X0, X0 + W, Y0, Y0 + W), SLATE, 2.5),
    Seg([cx(1), Y0, 0], [cx(1), Y0 + W, 0], SLATE, 2.5),
    Seg([cx(2), Y0, 0], [cx(2), Y0 + W, 0], SLATE, 2.5),
    map(range(0, 3), |k| center{[mid(k), Y0 + W + 0.28, 0]} Cap(str_join(["car at ", to_string(k + 1)]), 0.72, INK))
]
mesh inner = []
mesh keep = []
mesh panel = []

slide "You pick door 1. The car is behind each door with probability 1/3, so the square is cut into three equal columns."
    inner = map(range(0, 3), |k| center{[mid(k), Y0 + W / 2, 0]} Frac(1, 3, 0.9, SLATE))
    panel = [
        center{[1.95, 0.9, 0]} Cap("you picked door 1", 0.8, AZURE),
        center{[1.95, 0.2, 0]} Cap("area = probability", 0.78, SLATE)
    ]
    play Fade(0.7)

slide "Divide each column by what the host does. Car at 1: he opens door 2 or 3, half each. Car at 2: he must open 3. Car at 3: he must open 2."
    inner = []
    panel = []
    play Fade(0.3, [&inner, &panel])
    split = [
        Region(Rc(cx(0), cx(1), Y0 + W / 2, Y0 + W), tint(PLUM, 0.35)),
        Region(Rc(cx(1), cx(2), Y0, Y0 + W), tint(PLUM, 0.35)),
        Seg([cx(0), Y0 + W / 2, 0], [cx(1), Y0 + W / 2, 0], SLATE, 2.5)
    ]
    inner = [
        center{[mid(0), Y0 + W * 0.83, 0]} Cap("opens 3", 0.72, PLUM),
        center{[mid(0), Y0 + W * 0.66, 0]} Frac(1, 6, 0.8, PLUM),
        center{[mid(0), Y0 + W * 0.33, 0]} Cap("opens 2", 0.72, SLATE),
        center{[mid(0), Y0 + W * 0.16, 0]} Frac(1, 6, 0.8, SLATE),
        center{[mid(1), Y0 + W * 0.6, 0]} Cap("opens 3", 0.72, PLUM),
        center{[mid(1), Y0 + W * 0.43, 0]} Frac(1, 3, 0.8, PLUM),
        center{[mid(2), Y0 + W * 0.6, 0]} Cap("opens 2", 0.72, SLATE),
        center{[mid(2), Y0 + W * 0.43, 0]} Frac(1, 3, 0.8, SLATE)
    ]
    panel = [
        center{[1.95, 0.9, 0]} Cap("purple:", 0.8, PLUM),
        center{[1.95, 0.45, 0]} Cap("host opens door 3", 0.8, PLUM),
        center{[1.95, -0.45, 0]} Cap("gray:", 0.8, SLATE),
        center{[1.95, -0.9, 0]} Cap("host opens door 2", 0.8, SLATE)
    ]
    play Fade(0.7)

slide "He opened door 3, so only the purple regions remain. The car-at-2 region is twice the car-at-1 region."
    panel = []
    play Fade(0.3, [&panel])
    keep = [
        Outline(Rc(cx(0), cx(1), Y0 + W / 2, Y0 + W), PLUM, 4.5),
        Outline(Rc(cx(1), cx(2), Y0, Y0 + W), PLUM, 4.5)
    ]
    panel = [
        center{[1.95, 1.75, 0]} Cap("host opens door 3", 0.8, PLUM),
        center{[1.95, 1.15, 0]} Math("\frac{1}{6} + \frac{1}{3} = \frac{1}{2}", 0.9, PLUM),
        center{[1.95, 0.3, 0]} Cap("car at door 1", 0.78, AZURE),
        center{[1.95, -0.3, 0]} Math("\frac{1/6}{1/2} = \frac{1}{3}", 0.9, AZURE),
        center{[1.95, -1.1, 0]} Cap("car at door 2", 0.78, LEAF),
        center{[1.95, -1.7, 0]} Math("\frac{1/3}{1/2} = \frac{2}{3}", 0.9, LEAF)
    ]
    play Fade(0.7)

Uses the shared definitions for this lesson's figures.

The picture shows where the intuition goes wrong. Before the host acts, each door has $\frac13$. The host then opens door 3 in half of the games where the car is behind door 1, and in all of the games where it is behind door 2. Seeing door 3 open is therefore twice as likely when the car is behind door 2 as when it is behind door 1, and the evidence favors door 2 by two to one.

There is a second thing to read off. $P(C_1 \mid E) = \frac13$, the same as $P(C_1)$ before the host did anything. Under rule 4 the host opens door 3 with probability $\frac12$ whether or not the car is behind door 1, so what he does is independent of whether your first pick was right, and it cannot change your door’s probability. The $\frac13$ that belonged to door 3 does not get shared out. All of it goes to door 2.

Third solution: a hundred doors

The first two arguments are correct, and many people who follow every line still feel that the two doors ought to be even. For them there is a third argument, which changes the numbers until the intuition gives way.

Play the same game with 100 doors: one car, 99 goats. You pick a door. The host, who knows where the car is, opens 98 of the other 99 doors, all goats, leaving your door and one other closed.

The Monty Hall game with 100 doors. You pick one door (blue), which hides the car with probability 1 in 100. The host, who knows where the car is, then opens 98 goat doors and leaves exactly one other door closed (gold). That door carries the remaining 99 in 100.
Monocurl source
let N = 100
let YOURS = to_int(floor(N * rnd(7, 1)))
let CAR = to_int(floor(N * rnd(7, 2)))
var left = CAR
if (CAR == YOURS) {
    left = to_int(mod(YOURS + 1 + floor((N - 1) * rnd(7, 3)), N))
}
let LEFT = left
let dpos = |i| [-3.4 + mod(i, 10) * 0.46, 1.8 - (i // 10) * 0.4, 0]
let Wall = |s| block {
    for (i in range(0, N)) {
        var col = tint(SLATE, 0.4)
        var edge = SLATE
        if (i == YOURS) {
            col = lerp(tint(SLATE, 0.4), AZURE, sm(s * 2))
            edge = lerp(SLATE, AZURE, sm(s * 2))
        } else if (i == LEFT) {
            col = lerp(tint(SLATE, 0.4), GOLD, sm((s - 2.2) * 2))
            edge = lerp(SLATE, GOLD, sm((s - 2.2) * 2))
        } else {
            let o = sm((s - 1 - i / N) * 6)
            col = lerp(tint(SLATE, 0.4), PAPER, o)
            edge = lerp(SLATE, MIST, o)
        }
        . center{dpos(i)} fill{col} stroke{edge, 2} Rect([0.38, 0.32])
    }
    . center{[2.5, 1.6, 0]} Cap("your door", 1.0, alpha{sm(s * 2)} AZURE)
    . center{[2.5, 1.0, 0]} Cap("1 in 100", 1.2, alpha{sm(s * 2)} AZURE)
    . center{[2.5, 0.05, 0]} Cap("the other 99", 1.0, alpha{sm(s * 2) * (1 - sm((s - 2.2) * 3))} INK)
    . center{[2.5, 0.05, 0]} Cap("the one left closed", 1.0, alpha{sm((s - 2.6) * 3)} GOLD)
    . center{[2.5, -0.55, 0]} Cap("99 in 100", 1.2, alpha{sm(s * 2)} lerp(INK, GOLD, sm((s - 2.6) * 3)))
    . center{[2.5, -1.55, 0]} Cap("98 opened: goats", 0.9, alpha{sm((s - 1.5) * 2)} SLATE)
}
mesh wall = Wall(s: 0)

slide "open"
    play Wait(0.6)
    wall.s = 1
    play Lerp(1.4, [&wall], linear)
    play Wait(0.8)
    wall.s = 2.2
    play Lerp(3.2, [&wall], linear)
    play Wait(0.4)
    wall.s = 3.2
    play Lerp(1.6, [&wall], linear)
    play Wait(2.2)

Uses the shared definitions for this lesson's figures.

Nobody watching the host walk down the line, opening door after door and conspicuously skipping one, believes the skipped door is a coin flip against their own. Your first pick was a 1 in 100 shot and still is. In the other 99 games out of 100 the car is among the doors you did not pick, and the host, who is not allowed to reveal it, has no choice but to leave it closed.

Pause and try

With $n$ doors, of which the host opens $n - 2$, what is the probability that switching wins? Check your formula at $n = 3$ and $n = 100$.

Show answerHide answer

Switching wins exactly when the first pick is wrong, which has probability $\frac{n-1}{n}$: that is $\frac23$ for three doors and $\frac{99}{100}$ for a hundred.

The three-door game is the same game with the contrast turned down. The general statement uses only rules 1 to 3.

Notice that this proof says nothing about which goat door the host opens when he has a choice. Rule 4 was not used. The theorem is about how often each strategy wins over many games. The Bayes calculation answered a finer question, the probability given the particular door you saw opened, and that one does depend on rule 4, as the worked examples will show.

The chance of winning by staying (orange) and by switching (green) when the host opens all but one of the other doors, for games with 3, 4, 10 and 100 doors. Staying wins 1 time in n and switching wins the rest.
The chance of winning by staying (orange) and by switching (green) when the host opens all but one of the other doors, for games with 3, 4, 10 and 100 doors. Staying wins 1 time in $n$ and switching wins the rest.
Monocurl source
let NS = [3, 4, 10, 100]
let fb = Frame(0, 4, 0, 1.12, [0.2, 0.0, 0], 6.2, 2.9)
mesh frame = [
    GridLines(fb, [], [0.25, 0.5, 0.75, 1]),
    Seg(at(fb, 0, 0), at(fb, 4, 0), SLATE, 2.5),
    Seg(at(fb, 0, 0), at(fb, 0, 1.1), SLATE, 2.5),
    map([0.25, 0.5, 0.75, 1], |v| center{[fx(fb, 0) - 0.42, fy(fb, v), 0]} Math(to_string(v, 2), 0.74, SLATE)),
    center{[fx(fb, 0) + 1.15, fy(fb, 1.12) + 0.3, 0]} Note("chance of winning", 0.74)
]
mesh bars = map(range(0, 4), |i| [
    Box(at(fb, i + 0.3, 1 / NS[i] / 2), [0.5, max(2.9 / 1.12 / NS[i], 0.02)], EMBER, 0.35, 3),
    Box(at(fb, i + 0.7, (NS[i] - 1) / NS[i] / 2), [0.5, 2.9 / 1.12 * (NS[i] - 1) / NS[i]], LEAF, 0.35, 3),
    center{at(fb, i + 0.3, 1 / NS[i]) + [0, 0.33, 0]} Frac(1, NS[i], 0.72, EMBER),
    center{at(fb, i + 0.7, (NS[i] - 1) / NS[i]) + [0, 0.33, 0]} Frac(NS[i] - 1, NS[i], 0.72, LEAF),
    center{[fx(fb, i + 0.5), fy(fb, 0) - 0.35, 0]} Cap(str_join([to_string(NS[i]), " doors"]), 0.78, INK)
])

Uses the shared definitions for this lesson's figures.

What the host’s knowledge does

Every argument so far leaned on rule 3. To see how much weight it carries, change it. Suppose the host does not know where the car is. He opens one of the two doors you did not pick by flipping a coin, and it happens to reveal a goat. From where you stand the scene is identical: your door, one open door with a goat, one other closed door. Should you still switch?

Pause and try

With an ignorant host there are six equally likely cases: three places for the car, times two doors the host might open. You picked door 1. List the six cases, cross out those in which the host reveals the car, and find the probability that switching wins among the rest.

Show answerHide answer

Car at 1, opens 2: goat. Car at 1, opens 3: goat. Car at 2, opens 2: car revealed. Car at 2, opens 3: goat. Car at 3, opens 2: goat. Car at 3, opens 3: car revealed. Four cases survive and they are equally likely. In two of them the car is behind your door and in two it is behind the other closed door. Switching wins with probability $\frac24 = \frac12$.

  1. You pick door 1. The car has three possible places and the host’s coin picks door 2 or door 3 to open: six equally likely cases.
  2. In two of the six cases the host’s random door reveals the car. That did not happen, so those cases are ruled out.
  3. Four equally likely cases remain. Staying wins in two of them and switching wins in two: an even chance.
The game with a host who does not know where the car is and opens door 2 or door 3 at random, after you pick door 1. Of the six equally likely cases, two reveal the car and are discarded. In the four that remain, staying and switching each win twice.
Monocurl source
let colx = |d| -3.05 + d * 1.1
let ry = |r| 1.2 - r * 0.56
let SIZE = [1.0, 0.44]
# row r: car at r // 2, host opens door 1 + mod(r, 2) (index 1 or 2)
let car_of = |r| r // 2
let open_of = |r| 1 + to_int(mod(r, 2))
let shows_car = |r| car_of(r) == open_of(r)
let LIVE = filter(range(0, 6), |r| not shows_car(r))
mesh head = [
    center{[colx(0), 1.78, 0]} Cap("1 (yours)", 0.74, AZURE),
    center{[colx(1), 1.78, 0]} Cap("door 2", 0.74, INK),
    center{[colx(2), 1.78, 0]} Cap("door 3", 0.74, INK)
]
mesh cells = map(range(0, 6), |r| map(range(0, 3), |d| Behind([colx(d), ry(r), 0], d == car_of(r), SIZE)))
mesh opened = map(range(0, 6), |r| Mark([colx(open_of(r)), ry(r), 0], PLUM, SIZE, 4))
mesh shows = []
mesh strike = []
mesh verdicts = []

slide "You pick door 1. The car has three possible places and the host's coin picks door 2 or door 3 to open: six equally likely cases."
    play Fade(0.7)

slide "In two of the six cases the host's random door reveals the car. That did not happen, so those cases are ruled out."
    shows = [
        center{[0.75, 1.78, 0]} Cap("shows", 0.74, PLUM),
        map(range(0, 6), |r| center{[0.75, ry(r), 0]} Cap(["goat", "car"][shows_car(r)], 0.76, [PLUM, ROSE][shows_car(r)]))
    ]
    strike = map(filter(range(0, 6), |r| shows_car(r)), |r| Seg([colx(0) - 0.6, ry(r), 0], [1.25, ry(r), 0], ROSE, 4))
    play Fade(0.7)

slide "Four equally likely cases remain. Staying wins in two of them and switching wins in two: an even chance."
    verdicts = [
        center{[2.1, 1.78, 0]} Cap("stay", 0.76, INK),
        center{[3.1, 1.78, 0]} Cap("switch", 0.76, INK),
        map(LIVE, |r| [Verdict([2.1, ry(r), 0], car_of(r) == 0), Verdict([3.1, ry(r), 0], car_of(r) != 0)])
    ]
    play Fade(0.7)

Uses the shared definitions for this lesson's figures.

Bayes’ theorem gives the same answer and shows which number changed. With $E$ now meaning “the host opens door 3 and it shows a goat”:

$$ P(E \mid C_1) = \tfrac12, \qquad P(E \mid C_2) = \tfrac12, \qquad P(E \mid C_3) = 0, $$

so $P(C_2 \mid E) = \frac{\frac12 \cdot \frac13}{\frac12 \cdot \frac13 + \frac12 \cdot \frac13} = \frac12$. Compare with the knowing host, for whom $P(E \mid C_2)$ was 1. A host who knows the car is behind door 2 opens door 3 every time. A host who is guessing opens door 3 only half the time, and the other half he ruins the game by revealing the car. For the ignorant host, a goat behind door 3 is exactly as expected whether the car is behind door 1 or door 2, so it favors neither.

What you see is the same in both stories. What it tells you depends on the process that produced it. The simulation below plays the same 3000 deals with both hosts.

A simulation of 3000 games played with two different hosts. Green: the host knows where the car is and always shows a goat. Purple: the host opens a random door, and only the games where he happens to show a goat are counted. The share of games that switching wins settles near 2/3 for the knowing host and near 1/2 for the ignorant one.
Monocurl source
let NG = 3000
var idx = []
for (k in range(1, 41)) {
    idx .= k
}
for (k in range(50, NG + 1, 10)) {
    idx .= k
}
let IDX = idx
var know = []
var blind = []
var kw = 0
var bw = 0
var bn = 0
var q = 0
for (i in range(1, NG + 1)) {
    let car = pick3(i, 4)
    let mine = pick3(i, 5)
    let wrong = car != mine
    kw = kw + wrong
    # the ignorant host opens one of the two other doors by coin flip
    let other = to_int(mod(mine + 1 + (rnd(i, 6) < 0.5), 3))
    if (other != car) {
        bn = bn + 1
        bw = bw + wrong
    }
    if (i == IDX[q]) {
        know .= kw / i
        blind .= bw / max(bn, 1)
        q = min(q + 1, len(IDX) - 1)
    }
}
let KNOW = know
let BLIND = blind
let fs = Frame(0, NG, 0, 1, [-0.95, 0.1, 0], 4.7, 2.9)
let Run = |j| {
    let k = to_int(floor(j))
    return [
        Path(map(range(0, k + 1), |m| at(fs, IDX[m], BLIND[m])), PLUM, 3),
        Path(map(range(0, k + 1), |m| at(fs, IDX[m], KNOW[m])), LEAF, 3),
        center{[3.0, 0.85, 0]} scale{1.25} color{LEAF} Number(KNOW[k], 3),
        center{[3.0, -0.95, 0]} scale{1.25} color{PLUM} Number(BLIND[k], 3)
    ]
}
mesh frame = [
    GridLines(fs, [1000, 2000, 3000], [0.25, 0.5, 0.75, 1]),
    Axes(fs),
    XTicks(fs, [1000, 2000, 3000]),
    YTicks(fs, [0.25, 0.5, 0.75, 1], SLATE, 2),
    center{[fx(fs, 1500), fy(fs, 0) - 0.68, 0]} Note("games played", 0.74),
    center{[fx(fs, 0) + 1.55, fy(fs, 1) + 0.42, 0]} Note("share won by switching", 0.74),
    center{[3.0, 1.8, 0]} Cap("simulation", 0.76, SLATE),
    center{[3.0, 1.35, 0]} Cap("host knows", 0.78, LEAF),
    center{[3.0, -0.15, 0]} Cap("host guesses,", 0.76, PLUM),
    center{[3.0, -0.5, 0]} Cap("goat shown", 0.76, PLUM)
]
mesh targets = [
    stroke{SLATE, 2} dashed{[0.12, 0.08]} Line(at(fs, 0, 2 / 3), at(fs, NG, 2 / 3)),
    stroke{SLATE, 2} dashed{[0.12, 0.08]} Line(at(fs, 0, 1 / 2), at(fs, NG, 1 / 2))
]
mesh run = Run(j: 1)

slide "run"
    play Wait(0.5)
    run.j = len(IDX) - 1
    play Lerp(7, [&run], linear)
    play Wait(1.8)

Uses the shared definitions for this lesson's figures.

Worked examples

Common mistakes

Stepping back

The arithmetic here is three fractions. The difficulty is that the host’s action feels like plain information, “door 3 has a goat”, when it is the output of a procedure. A knowing host is constrained by where the car is, and his choice therefore leaks information about it. Under the standard rules the leak says nothing about your door and everything about the other one.

The reusable habit is the one Bayes’ theorem enforces. When you learn something, ask how probable it was that you would learn exactly that under each hypothesis. Hypotheses that made the observation more probable gain, in proportion. Counting the possibilities that remain is not a substitute.

Check yourself

In the standard game you pick door 1 and the host opens door 2, showing a goat. What is the probability that the car is behind door 3?

Problems

The first three repeat the lesson’s arguments with new numbers. The next three change the rules. The last two connect the problem to other settings.

Problem 1

There are 5 doors with one car. You pick a door, and the host, who knows where the car is, opens 3 goat doors among the other four. What is the probability of winning if you stay, and if you switch to the other closed door?

Show solutionHide solution

Your first pick is right with probability $\frac15$, and the host’s actions do not change that, so staying wins with probability $\frac15$. If the first pick is wrong, which has probability $\frac45$, the car is among the other four doors, and the host must leave it closed while opening the other three. So switching wins with probability $\frac45$.

Problem 2

Imagine 300 standard games in which you pick door 1 every time, and suppose the car is behind each door in exactly 100 of them and the host’s coin splits evenly. In how many games does the host open door 3? In how many of those is the car behind door 2?

Show solutionHide solution

Car behind door 1 (100 games): the host opens door 2 in 50 and door 3 in 50. Car behind door 2 (100 games): he opens door 3 in all 100. Car behind door 3 (100 games): he opens door 2 in all 100. So he opens door 3 in $50 + 100 = 150$ games, and in 100 of those the car is behind door 2. That is $\frac{100}{150} = \frac23$, the Bayes calculation in whole numbers.

Problem 3

A friend says: “Once door 3 is open, the situation is symmetric between doors 1 and 2. Each is a closed door that might hide the car. So by symmetry they have equal probability.” Identify precisely what breaks the symmetry.

Show solutionHide solution

Symmetry would require that the two doors were treated alike by the process that led here, and they were not. Door 1 was protected: by rule 3 the host could not open it whatever was behind it, so its staying closed carries no information. Door 2 was exposed: the host was free to open it and would have done so in half the games where the car is behind door 1, but was forbidden to in every game where the car is behind door 2. Its staying closed is evidence. In numbers, “door 2 stays closed” has probability $\frac12$ if the car is behind door 1 and probability 1 if it is behind door 2.

Problem 4

There are 4 doors with one car. You pick a door, and the host, who knows where the car is, opens one goat door among the other three, choosing at random among the goat doors available to him. You then switch to one of the two other closed doors, chosen at random. What is your probability of winning? Is switching still better than staying?

Show solutionHide solution

Staying wins with probability $\frac14$. If the first pick is wrong, which has probability $\frac34$, the car is behind one of the two other closed doors, and a random choice between them finds it with probability $\frac12$. If the first pick is right, switching loses. So switching wins with probability $\frac34 \cdot \frac12 = \frac38$, which is more than $\frac14$. Check: by symmetry the two other closed doors have equal probability, and $\frac14 + \frac38 + \frac38 = 1$.

Problem 5

An ignorant host plays the three-door game: he opens one of the two doors you did not pick at random. If he reveals the car, the game is void and you win nothing. If he reveals a goat, you switch. (a) What is the probability that the game is void? (b) What is the probability that you win the car? (c) Would always staying do better?

Show solutionHide solution

Use the six equally likely cases from the lesson. (a) The car is revealed in 2 of 6 cases: $\frac13$. (b) You win by switching in the cases where the car is behind the other closed door and a goat was shown: car at 2 with door 3 opened, and car at 3 with door 2 opened. That is 2 of 6: $\frac13$. (c) Staying wins when the car is behind door 1 and the game is not void, which is also 2 of 6. The two strategies are equally good, consistent with the conditional probability $\frac12$: each wins half of the $\frac23$ of games that are not void.

Problem 6

A host follows rules 1 to 3, and when he has a choice between doors 2 and 3 he opens door 3 with probability $q$, where $0 \le q \le 1$. You pick door 1. (a) Find $P(C_2 \mid \text{he opens door 3})$ and $P(C_3 \mid \text{he opens door 2})$ in terms of $q$. (b) Show that both are at least $\frac12$, so switching is never worse than staying whatever you see. (c) Verify that the overall probability that switching wins is $\frac23$ for every $q$.

Show solutionHide solution

(a) For “opens door 3”: the probabilities under $C_1, C_2, C_3$ are $q$, 1, 0, so $P(C_2 \mid \text{opens 3}) = \frac{\frac13}{\frac13 q + \frac13} = \frac{1}{1 + q}$. For “opens door 2”: the probabilities are $1 - q$, 0, 1, so $P(C_3 \mid \text{opens 2}) = \frac{1}{(1 - q) + 1} = \frac{1}{2 - q}$.

(b) Since $0 \le q \le 1$, both denominators $1 + q$ and $2 - q$ lie between 1 and 2, so both probabilities lie between $\frac12$ and 1.

(c) $P(\text{opens 3}) = \frac{1 + q}{3}$ and $P(\text{opens 2}) = \frac{2 - q}{3}$. So the probability that switching wins is

$$ \frac{1+q}{3} \cdot \frac{1}{1+q} + \frac{2-q}{3} \cdot \frac{1}{2-q} = \frac13 + \frac13 = \frac23. $$

The case $q = \frac12$ is rule 4, and $q = 0$ is the lazy host of the worked example.

Problem 7

In the 100-door game, suppose the host does not know where the car is. He opens 98 of the other 99 doors at random, and all 98 happen to show goats. What is the probability that the car is behind your door?

Show solutionHide solution

Let $E$ be “the 98 opened doors all show goats”. If the car is behind your door, every other door hides a goat and $E$ is certain: $P(E \mid \text{yours}) = 1$. If the car is behind a particular other door $j$, then $E$ happens only if door $j$ is the one the host leaves closed. He leaves each of the 99 doors closed with equal probability, so $P(E \mid \text{car at } j) = \frac{1}{99}$. By Bayes’ theorem,

$$ P(\text{yours} \mid E) = \frac{1 \cdot \frac{1}{100}}{1 \cdot \frac{1}{100} + 99 \cdot \frac{1}{99} \cdot \frac{1}{100}} = \frac{1/100}{2/100} = \frac12. $$

With an ignorant host the two closed doors are equally likely even with 100 doors. Surviving 98 random openings is strong evidence, and it is equally strong for your door and for the other one, since each had to be lucky in the same way.

Problem 8

(Bertrand’s boxes.) Three boxes each hold two coins: one has two gold coins, one has two silver coins, and one has one of each. You choose a box at random and draw one of its coins at random. It is gold. What is the probability that the other coin in the same box is also gold? Explain the connection to the Monty Hall problem.

Show solutionHide solution

The tempting answer is $\frac12$: the box is either gold-gold or gold-silver. But those two boxes are not equally likely given what you saw. There are three gold coins, each equally likely to be the one you drew: two of them are in the gold-gold box and one is in the mixed box. So the other coin is gold with probability $\frac23$. By Bayes’ theorem: $P(\text{gold drawn} \mid GG) = 1$, $P(\text{gold drawn} \mid GS) = \frac12$, $P(\text{gold drawn} \mid SS) = 0$, so $P(GG \mid \text{gold}) = \frac{1 \cdot \frac13}{1 \cdot \frac13 + \frac12 \cdot \frac13} = \frac23$. The numbers $1, \frac12, 0$ are the same three numbers as in the Monty Hall calculation, and the error is the same: two possibilities remain, and one of them was twice as likely to produce the observation.

Shared definitions used by this lesson's figures
# house kit: prepended to every essay figure after the std imports

# palette. AZURE and EMBER are the two actors, LEAF marks an answer, ROSE a problem
let PAPER = [1, 1, 1, 1]
let INK = [0.08, 0.09, 0.11, 1]
let SLATE = [0.40, 0.44, 0.50, 1]
let MIST = [0.85, 0.86, 0.88, 1]
let AZURE = [0.13, 0.42, 0.68, 1]
let EMBER = [0.89, 0.42, 0.12, 1]
let LEAF = [0.13, 0.55, 0.36, 1]
let ROSE = [0.78, 0.22, 0.24, 1]
let PLUM = [0.47, 0.30, 0.66, 1]
let GOLD = [0.85, 0.62, 0.08, 1]

background = PAPER

# an opaque pastel of col; use for fills so overlaps do not darken
let tint = |col, amount = 0.18| [
    1 - (1 - col[0]) * amount,
    1 - (1 - col[1]) * amount,
    1 - (1 - col[2]) * amount,
    1
]

# text: Cap for labels, Note for quiet labels, Math for typeset maths
let Cap = |txt, size = 0.75, col = INK| color{col} Text(txt, size, "Charter")
let Note = |txt, size = 0.65| color{SLATE} Text(txt, size, "Charter")
let Math = |tex, size = 0.9, col = INK| color{col} Tex(tex, size)

# a paper rectangle to sit behind text that crosses lines
let Plate = |pos, size| center{pos} fill{PAPER} stroke{alpha{0} PAPER, 0} Rect(size)

# shapes with fill and stroke both set, so no stray black appears
let Pt = |pos, col = INK, r = 0.075| center{pos} fill{col} stroke{col, 1} Circle(r, 48)
let Ring = |pos, col = INK, r = 0.1, w = 3| center{pos} fill{PAPER} stroke{col, w} Circle(r, 48)
let Seg = |a, b, col = INK, w = 3| stroke{col, w} Line(a, b)
let Path = |pts, col = INK, w = 3| stroke{col, w} Polyline(pts)
let Region = |pts, col| fill{col} stroke{alpha{0} col, 0} Polygon(pts)
let Outline = |pts, col = INK, w = 3| fill{alpha{0} PAPER} stroke{col, w} Polygon(pts)
let Shape = |pts, col, amount = 0.18, w = 3| fill{tint(col, amount)} stroke{col, w} Polygon(pts)
let Disc = |pos, r, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Circle(r, 96)
let Box = |pos, size, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Rect(size)
# a line from a to b ending in a small solid arrowhead
let Tip = |a, b, col = INK, w = 3, head = 0.17| {
    let d = normalize([b[0] - a[0], b[1] - a[1], 0])
    let n = [-d[1], d[0], 0]
    let base = [b[0] - d[0] * head, b[1] - d[1] * head, 0]
    return [
        stroke{col, w} Line(a, base),
        fill{col} stroke{col, 1} Polygon([
            b,
            [base[0] + n[0] * head * 0.42, base[1] + n[1] * head * 0.42, 0],
            [base[0] - n[0] * head * 0.42, base[1] - n[1] * head * 0.42, 0]
        ])
    ]
}

# plots. a frame is [x0, x1, y0, y1, centre, width, height]: a data window and the scene box it fills
let Frame = |x0, x1, y0, y1, c = [0, 0, 0], w = 6.4, h = 3.6| [x0, x1, y0, y1, c, w, h]
let fx = |fr, x| fr[4][0] + (x - (fr[0] + fr[1]) / 2) * fr[5] / (fr[1] - fr[0])
let fy = |fr, y| fr[4][1] + (y - (fr[2] + fr[3]) / 2) * fr[6] / (fr[3] - fr[2])
let at = |fr, x, y| [fx(fr, x), fy(fr, y), 0]

# axes through the data origin (or the nearest edge of the window), with optional names
let Axes = |fr, x_name = "", y_name = "", col = SLATE| {
    let ox = clamp(fr[0], 0, fr[1])
    let oy = clamp(fr[2], 0, fr[3])
    var parts = [
        Tip(at(fr, fr[0], oy), [fx(fr, fr[1]) + 0.25, fy(fr, oy), 0], col, 2.5, 0.15),
        Tip(at(fr, ox, fr[2]), [fx(fr, ox), fy(fr, fr[3]) + 0.25, 0], col, 2.5, 0.15)
    ]
    if (x_name != "") {
        parts .= center{[fx(fr, fr[1]) + 0.5, fy(fr, oy), 0]} Math(x_name, 0.8, col)
    }
    if (y_name != "") {
        parts .= center{[fx(fr, ox), fy(fr, fr[3]) + 0.5, 0]} Math(y_name, 0.8, col)
    }
    return parts
}

# tick marks with numbers at the listed data values
let XTicks = |fr, xs, col = SLATE, places = 0| block {
    let oy = fy(fr, clamp(fr[2], 0, fr[3]))
    for (x in xs) {
        . Seg([fx(fr, x), oy - 0.07, 0], [fx(fr, x), oy + 0.07, 0], col, 2)
        . center{[fx(fr, x), oy - 0.33, 0]} Math(to_string(x, places), 0.72, col)
    }
}
let YTicks = |fr, ys, col = SLATE, places = 0| block {
    let ox = fx(fr, clamp(fr[0], 0, fr[1]))
    for (y in ys) {
        . Seg([ox - 0.07, fy(fr, y), 0], [ox + 0.07, fy(fr, y), 0], col, 2)
        . center{[ox - 0.36, fy(fr, y), 0]} Math(to_string(y, places), 0.72, col)
    }
}

# faint grid lines at the listed data values
let GridLines = |fr, xs, ys, col = MIST| block {
    for (x in xs) {
        . Seg(at(fr, x, fr[2]), at(fr, x, fr[3]), col, 1.5)
    }
    for (y in ys) {
        . Seg(at(fr, fr[0], y), at(fr, fr[1], y), col, 1.5)
    }
}

# the graph of f over [a, b], drawn in the frame. values are clamped to the window
let Graph = |fr, f, a, b, col = AZURE, w = 4, n = 160|
    stroke{col, w} Polyline(map(sample(a, b, n), |x| at(fr, x, clamp(fr[2], f(x), fr[3]))))

# the region between the graph of f and the x axis over [a, b]
let AreaUnder = |fr, f, a, b, col = AZURE, amount = 0.2, n = 80| {
    var pts = [at(fr, a, 0)]
    for (x in sample(a, b, n)) {
        pts .= at(fr, x, clamp(fr[2], f(x), fr[3]))
    }
    pts .= at(fr, b, 0)
    return fill{tint(col, amount)} stroke{alpha{0} col, 0} Polygon(pts)
}

# double hash: std seeded_random is a single sine hash and its draws are overdispersed
let frac = |x| x - floor(x)
let rnd = |i, salt| frac(sin(i * 39.3468 + salt * 11.135 + frac(sin(i * 12.9898 + salt * 78.233) * 43758.5453) * 6.2831853) * 24634.6345)
let sm = |x| {
    let u = clamp(0, x, 1)
    return u * u * (3 - 2 * u)
}
let pick3 = |i, salt| to_int(floor(3 * rnd(i, salt)))
# a table cell showing what is behind a door: 1 for the car, 0 for a goat
let Behind = |pos, car, size = [1.02, 0.5]| [
    Box(pos, size, [SLATE, GOLD][car], [0.1, 0.32][car], 2),
    center{pos} Cap(["goat", "car"][car], 0.76, [SLATE, INK][car])
]
# a frame around a cell, for the door the host opens
let Mark = |pos, col = PLUM, size = [1.02, 0.5], w = 4.5| Outline([
    [pos[0] - size[0] / 2, pos[1] - size[1] / 2, 0], [pos[0] + size[0] / 2, pos[1] - size[1] / 2, 0],
    [pos[0] + size[0] / 2, pos[1] + size[1] / 2, 0], [pos[0] - size[0] / 2, pos[1] + size[1] / 2, 0]
], col, w)
let Verdict = |pos, win| center{pos} Cap(["loses", "wins"][win], 0.78, [ROSE, LEAF][win])
let Frac = |num, den, size = 1.0, col = INK| Math(str_join(["\frac{", to_string(num), "}{", to_string(den), "}"]), size, col)
let Rc = |x0, x1, y0, y1| [[x0, y0, 0], [x1, y0, 0], [x1, y1, 0], [x0, y1, 0]]