Chapter 157
Is This Bathroom Occupied?
Riddler Express
A class of children and their teacher stand in a circle, people in all. The teacher holds a fair coin and a potato. On each turn the teacher tosses the coin: whoever holds the potato passes it left on heads and right on tails. The game ends when every child except one has held the potato, and the remaining child wins. What is each child’s probability of winning?
The Riddler, FiveThirtyEight, August 4, 2017(original post)
Solution
Surprisingly, every child has the same probability of winning, , independently of where they stand in the circle.
Fix a child Carol, and let Anna and Bob be her two immediate neighbours in the circle (one of them may be the teacher). The potato starts with the teacher and moves by a simple symmetric random walk on the circle until it has visited every child but one. Carol wins precisely when she is the only child never visited, which is the same as saying that the potato reaches Anna and Bob without ever first reaching Carol, and at the moment the potato first lands on the second of the two, it has already touched every other child.
The cleanest way to see why comes out is to condition on which neighbour the potato visits first. Suppose the potato hits Anna before Bob. For Carol to win, the potato must after that moment travel all the way around the ring through the remaining children and land on Bob before ever coming back to Carol. The position of the potato is a random walk on the circle; once it stands on Anna, what matters is whether it reaches Bob before Carol. Lay the children out as a line by cutting the circle at Carol; Anna sits one step from Carol on one side and Bob is steps away on the other. The probability that an unbiased random walk starting at Anna reaches Bob before Carol is, by the standard gambler’s-ruin formula on a line of length , By the same argument, if the potato hits Bob first, Carol’s winning probability is again (the picture is the mirror image). The two cases are mutually exclusive and exhaust all possibilities, so the unconditional probability is the same weighted average, Carol was an arbitrary child, so every child has the same chance of winning.
A neat sanity check: the children’s probabilities must sum to , since exactly one child is left out, and . The teacher plays the role of starting position, not of a winner.
The computation
Simulate the actual game many times and tally how often each position survives unvisited. The simulator starts the potato with the teacher (index ) and tracks the set of visited children (indices to ); the game ends when of the children have been visited.
Place players around a circle, indexing the teacher and the children .
Hold the potato at index . Repeatedly flip a fair coin and move the potato or mod .
Record the set of children visited; stop when distinct children have held it.
The remaining child is the winner; tally the winner index over many trials.
import random
def play(rng):
pos = 0
visited = set()
while len(visited) < 29:
pos = (pos + (1 if rng.random() < 0.5 else -1)) % 31
if pos != 0:
visited.add(pos)
survivor = (set(range(1, 31)) - visited).pop()
return survivor
rng = random.Random(0)
wins = [0] * 31
trials = 300_000
for _ in range(trials):
wins[play(rng)] += 1
print([round(wins[i] / trials, 4) for i in range(1, 31)])
# all entries close to 0.0333 = 1/30
Each child’s empirical win rate clusters tightly around , confirming the uniform distribution.
Riddler Classic
An office bathroom has one toilet and a sign on the door that slides between “Vacant” and “Occupied”. Of the people who use the bathroom, are oblivious to the sign and never touch it (group U), slide it to “Occupied” on entering but forget to reset it on leaving (group S), and are conscientious: “Occupied” on entering, “Vacant” on leaving (group C). The bathroom is occupied exactly half of the time. Two questions: (a) given the sign reads “Occupied”, what is the probability the bathroom really is occupied? (b) given the sign reads “Vacant”, what is the probability the bathroom really is vacant? Extra credit: what happens as the fraction of conscientious users varies?
The Riddler, FiveThirtyEight, August 4, 2017(original post)
Solution
The key observation is that a U-user neither reads nor changes the sign, so the sign you see is determined by the most recent non-U user to have used the bathroom, together with whether that user is still inside. Equivalently, walk backwards through the stream of users until you find the first non-U (call them the latest setter); the sign reads whatever the latest setter left.
If the latest setter was a C and has left, the sign reads “Vacant”.
If the latest setter was a C and is still inside, the sign reads “Occupied”.
If the latest setter was an S (whether still inside or not), the sign reads “Occupied”.
Because among the non-U users C and S are equally likely (each of the population), the latest setter is independently either C or S, each with probability . We assume this independence: the type of the most recent non-U user is independent of whether the bathroom is occupied right now, which holds when bathroom occupancy at a random moment is governed by user arrival/departure statistics symmetric across types.
Building the joint distribution. Write and for “occupied” and “vacant” (the truth), and “Occ” / “Vac” for what the sign reads. Each visit is a Bernoulli trial: with probability the bathroom is occupied, and (given occupied) the current user is one of C, S, U each with probability . The latest non-U setter, independently, is C or S with probability each. Tabulating:
Occupied by C (): C entered, set sign to “Occupied”, currently inside, so .
Occupied by S (): S entered, set sign to “Occupied”, currently inside, so .
Occupied by U (): U doesn’t touch the sign; the sign reads what the latest non-U setter left. If they were S () the sign reads “Occupied”; if C () the sign reads “Vacant”. Contribution: each to and .
Vacant (): no one is inside, so the sign reads whatever the latest non-U setter left. S () gives “Occupied”; C () gives “Vacant”. Contribution: each to and .
Part (a). Add up the joint masses with sign reading “Occupied”: Of this, the bathroom is genuinely occupied with mass . Hence
Part (b). The remaining mass is , of which the bathroom really is vacant with mass , so
A vacant sign is the more trustworthy of the two: only a C user can have set it to “Vacant”, and even after they leave a U-user inside is the only way for the sign to be wrong. The “Occupied” sign, by contrast, is contaminated by S-users who leave it set whether they are inside or not.
Extra credit. Replace the equal thirds by population shares with , and condition the latest setter on being C or S, with probabilities and . The same construction yields The “Vacant” reliability depends only on the U fraction, dropping from (no obvious U-users) to (everyone is a U-user). The “Occupied” reliability climbs from (all S) to (all C), monotone in the C share. Intuition: conscientious users make every sign more accurate; oblivious users only degrade the “Vacant” reading.
The computation
Simulate an event-driven model: an infinite queue of visitors, each independently C, S, or U; bathroom occupancy alternates between empty and occupied for a single visitor. Track sign state and bathroom truth at random sampling moments.
Generate a stream of visitors with i.i.d. types in .
Alternate occupied / vacant intervals of equal expected length (one visitor per occupied interval, one “gap” of independent length between).
At the start of each gap and at the start of each occupied interval, record (sign reading, truth).
Estimate and .
import random
rng = random.Random(0)
N = 400_000
sign = "Vac"
samples = []
for _ in range(N):
t = rng.choice("CSU")
if t == "C": sign_enter = "Occ"; sign_exit = "Vac"
elif t == "S": sign_enter = "Occ"; sign_exit = "Occ"
else: sign_enter = sign_exit = sign
# gap before user: vacant interval
samples.append((sign, "V"))
sign = sign_enter
# while user is inside: occupied interval
samples.append((sign, "O"))
sign = sign_exit
occ_total = sum(1 for s, _ in samples if s == "Occ")
occ_true = sum(1 for s, t in samples if s == "Occ" and t == "O")
vac_total = sum(1 for s, _ in samples if s == "Vac")
vac_true = sum(1 for s, t in samples if s == "Vac" and t == "V")
print(round(occ_true / occ_total, 4)) # ~0.625 = 5/8
print(round(vac_true / vac_total, 4)) # ~0.75 = 3/4
Each side is sampled at uniform rate (one observation per visitor-arrival and one per visitor-departure), and the bathroom is occupied half the time by construction. The empirical conditionals match and to three digits.