Skip to content
Vamshi Jandhyala

Books · The Riddler

Chapter 160

Is Your Friend Full Of It?

Riddler Express

Your friend claims to have once made 1717 free throws in a row, having not touched a basketball for years. Assume he is a 70%70\% free-throw shooter. What is the expected number of free throws he would need to take before completing a streak of 1717 makes in a row? What if his accuracy were a little worse?

The Riddler, FiveThirtyEight, September 1, 2017(original post)

Solution

Let TLT_L be the number of trials a Bernoulli(pp) process needs to first produce a streak of LL consecutive successes. The expectation E[TL]\mathbb{E}[T_L] admits a clean closed form, E[TL]=1pL(1p)pL.\mathbb{E}[T_L] = \frac{1 - p^L}{(1 - p)\,p^L}. Derivation. Condition on the first failure. Let E=E[TL]E = \mathbb{E}[T_L]. At any point before a success streak of length LL is achieved, restart the clock at any failure. Consider the first attempt: with probability 1p1 - p it is a failure (one trial used, no progress), and with probability pp it is a success that begins a run. Continuing along a run of successes, if all LL shots in a row come up successes (probability pLp^L), we finish in LL trials; otherwise (probability 1pL1 - p^L) the streak is broken at some point inside the first LL trials, and we restart fresh from the failure.

Working out the expectation with a first-step argument on each shot in the streak: E[TL]=pLL+k=0L1pk(1p)(k+1+E[TL]).\mathbb{E}[T_L] = p^L \cdot L + \sum_{k=0}^{L-1} p^k (1-p) \big(k + 1 + \mathbb{E}[T_L]\big). The first term: with probability pLp^L the first LL shots are all successes; we finish in LL trials. The summand: with probability pk(1p)p^k(1-p) the first kk shots are successes and the (k+1)(k+1)th is a failure (using k+1k+1 trials), after which we start over with a fresh independent TLT_L. Expanding, E[TL]=LpL+(1p)k=0L1pk(k+1)+(1pL)E[TL].\mathbb{E}[T_L] = L p^L + (1-p) \sum_{k=0}^{L-1} p^k (k + 1) + (1 - p^L) \mathbb{E}[T_L]. Move the E[TL]\mathbb{E}[T_L] term to the left, pLE[TL]=LpL+(1p)k=0L1pk(k+1).p^L \,\mathbb{E}[T_L] = L p^L + (1-p) \sum_{k=0}^{L-1} p^k (k + 1). Use k=0L1(k+1)pk=ddpk=0L1pk+1=ddpp(1pL)1p\sum_{k=0}^{L-1} (k+1) p^k = \frac{d}{dp} \sum_{k=0}^{L-1} p^{k+1} = \frac{d}{dp} \cdot \frac{p(1 - p^L)}{1 - p}, which after simplification gives (1pL)/(1p)LpL/(1p)(1 - p^L)/(1 - p) - L p^L /(1 - p). Substituting and simplifying, E[TL]=1pL(1p)pL.\mathbb{E}[T_L] = \frac{1 - p^L}{(1 - p) p^L}.

Plugging in p=0.7p = 0.7, L=17L = 17: E[T17]=10.7170.30.717=0.71710.31429.55.\mathbb{E}[T_{17}] = \frac{1 - 0.7^{17}}{0.3 \cdot 0.7^{17}} = \frac{0.7^{-17} - 1}{0.3} \approx 1429.55.

E[T17]1,430 shots.\boxed{\,\mathbb{E}[T_{17}] \approx 1{,}430 \text{ shots.}\,}

The estimate is highly sensitive to pp because the dominant term is pLp^{-L}, which grows like a geometric in LL when pp shrinks. At p=0.6p = 0.6, E[T17]=(0.6171)/0.417,042\mathbb{E}[T_{17}] = (0.6^{-17} - 1)/0.4 \approx 17{,}042, about 1212 times longer. The friend’s claim is plausible at 70%70\% accuracy (a couple of hours’ practice) but quickly becomes unreasonable as the shooting percentage drops.

The computation

Simulate the actual experiment: trial after trial of Bernoulli(pp) shots, count the number of shots until the first run of length LL. Average over many trials.

  1. Initialise streak length to 00, trial count to 00.

  2. For each shot, increment trial count; flip a Bernoulli(pp); if heads, increment streak, else reset streak to 00.

  3. Stop when streak reaches LL; report trial count.

  4. Average over many trials and compare to the closed form.

import random
def first_run(L, p, rng):
    streak = n = 0
    while streak < L:
        n += 1
        streak = streak + 1 if rng.random() < p else 0
    return n

rng = random.Random(0)
trials = 30_000
mean = sum(first_run(17, 0.7, rng) for _ in range(trials)) / trials
print(round(mean, 1))                            # ~1430
# closed form
p, L = 0.7, 17
print(round((1 - p**L) / ((1 - p) * p**L), 2))   # 1429.55

The empirical mean clusters around the closed form to within sampling error.

Riddler Classic

Seven players each receive a uniformly-random black or white hat. Each can see the others’ hats but not her own. Each player simultaneously and independently writes down “black”, “white”, or “pass”. The team wins if at least one player guesses her own hat colour correctly and nobody guesses wrong; otherwise the team loses. The players may agree on a strategy beforehand but cannot communicate during the game. What is the best winning probability? Extra credit: 2N12^N - 1 players.

The Riddler, FiveThirtyEight, September 1, 2017(original post)

Solution

The team can win with probability 7/87/8 using a strategy built from the Hamming code. More generally, with n=2N1n = 2^N - 1 players the team can win with probability (2N1)/2N(2^N - 1)/2^N.

The trick. Label the players with the nonzero binary strings of length N=3N = 3: Anna =001= 001, Ben =010= 010, Clarice =011= 011, Doug =100= 100, Edna =101= 101, Fred =110= 110, Georgina =111= 111. Each player pp, seeing the others’ hats, computes the bitwise XOR (i.e., addition modulo 22 component-wise) of the labels of all teammates wearing a black hat. Call this value sps_p. The rule is:

  • If sp=000s_p = 000, guess “black”.

  • If sps_p equals the player’s own label, guess “white”.

  • Otherwise, pass.

Why it works. Let SS be the XOR of the labels of all black-hat wearers. Each player pp sees everyone else, so for pp:

  • If pp’s hat is white, then sp=Ss_p = S (her own label contributes 00).

  • If pp’s hat is black, then sp=Sps_p = S \oplus p (her label cancels out of the sum).

Player pp guesses black iff sp=000s_p = 000; she guesses white iff sp=ps_p = p.

Now consider the value of SS over a uniform random colouring of all seven hats:

  • Case S=000S = 000. This means the XOR of all black labels is 00. Every player pp has sp=s_p = XOR with or without her own label; specifically, sp=ps_p = p if she has a black hat, sp=000s_p = 000 if white. So every white-hat player guesses “black” and is wrong, and every black-hat player guesses “white” and is wrong. The team loses.

  • Case S000S \neq 000. Then S{001,010,,111}S \in \{001, 010, \ldots, 111\}, the binary string of some specific player. For this player p=Sp^* = S: if her hat is black, sp=Sp=000s_{p^*} = S \oplus p^* = 000, she guesses “black” correctly. If her hat is white, sp=S=ps_{p^*} = S = p^*, she guesses “white” correctly. Either way, pp^* guesses correctly. Every other player pp has sp000s_p \neq 000 and spps_p \neq p, so passes. The team wins.

The team wins precisely when S000S \neq 000. Since the seven hats are i.i.d. uniform, SS is uniform over {0,1}3\{0, 1\}^3 (any single hat colour, conditional on the others, makes SS equally likely to be any value), so Pr(S000)=7/8\Pr(S \neq 000) = 7/8.

Pr(win)=78.\boxed{\,\Pr(\text{win}) = \tfrac{7}{8}.\,}

Optimality. No strategy does better than 7/87/8. Consider the expected number of correct guesses minus wrong guesses across all 272^7 colourings. Each individual player guesses correctly on exactly half the colourings she does not pass on (her own hat is independent of what she sees), so the per-player correct-minus-wrong total is zero. Summed across players, the total correct-minus-wrong is 00. Each colouring contributes either +1+1 (one correct guess, others pass: team wins) or some negative quantity (any wrong guess: team loses); for the totals to sum to zero, the winning colourings exactly balance the wrong-guess contributions. The maximum is achieved when every winning colouring contributes exactly +1+1 and every losing colouring contributes exactly 1-1 (one wrong guess), with 7/87/8 of colourings winning. This balance is achieved by the Hamming strategy.

Extra credit. With n=2N1n = 2^N - 1 players, label players by the nonzero binary strings of length NN. The same XOR strategy applies, and the team wins iff the XOR of all black-hat labels is nonzero, which happens with probability (2N1)/2N(2^N - 1)/2^N.

The computation

Enumerate all 27=1282^7 = 128 hat colourings; for each, run the XOR strategy for each player; count the colourings in which the team wins.

  1. For each player p{1,,7}p \in \{1, \ldots, 7\} (binary labels 001,,111001, \ldots, 111) and each colouring (a 77-bit string bb):

  2. Compute sp=s_p = XOR of labels of teammates with bi=1b_i = 1.

  3. If sp=0s_p = 0, guess black; if sp=ps_p = p, guess white; else pass.

  4. Team wins iff at least one guess is correct and no guess is wrong.

n = 7
labels = list(range(1, n + 1))   # 001..111 in binary
wins = 0
for b in range(1 << n):
    hats = [(b >> i) & 1 for i in range(n)]
    correct = wrong = 0
    for p in range(n):
        s = 0
        for q in range(n):
            if q != p and hats[q] == 1:
                s ^= labels[q]
        if s == 0:
            guess = 1                            # black
        elif s == labels[p]:
            guess = 0                            # white
        else:
            guess = None
        if guess is None:
            continue
        if guess == hats[p]: correct += 1
        else: wrong += 1
    if wrong == 0 and correct >= 1:
        wins += 1
print(wins, wins / (1 << n))                     # 112  0.875

The team wins on exactly 112=7128/8112 = 7 \cdot 128 / 8 of the 128128 colourings, confirming Pr(win)=7/8\Pr(\text{win}) = 7/8.