Books · The Fiddler: Solutions
Chapter 79
Can You Solve the Tricky Mathematical Treat?
A trick-or-treat host hands you an enormous bag containing exactly three peanut butter cups, your favourite, with the rest of the bag filled with individual candy corn kernels, not your favourite. You have no idea how many kernels there are: any whole number, including zero, seems equally likely. You draw three candies at random, one after another, and every one is a peanut butter cup. Whatever remains is candy corn. How many kernels do you expect are left in the bag?
The Fiddler, Zach Wissner-Gross, October 25, 2024(original post)
Solution
Start from a flat prior: before drawing, the number of kernels is equally likely to be any of . If there are kernels, the bag holds candies, and the chance of drawing three peanut butter cups in a row is After seeing three cups, the posterior weight on is proportional to this. Two telescoping sums finish it, so the posterior mean is : candy corn kernel. The three draws are strong evidence the bag is nearly all peanut butter cups, and a single expected kernel is what survives.
The computation
Form the posterior directly: weight each by the probability of drawing three cups, then take the weighted mean of . The truncated sum closes in on .
from fractions import Fraction as F
S = Sn = F(0)
for n in range(200000):
w = F(6, (n + 1) * (n + 2) * (n + 3)) # posterior weight (flat prior)
S += w; Sn += n * w
print(float(Sn / S)) # -> 1.0
Extra Credit
Now the bag has peanut butter cups (), and you draw of them in a row (). How many kernels do you expect remain?
Solution
With kernels the probability of drawing cups in a row is , so the posterior weight on is proportional to , a product of consecutive reciprocals. The same telescoping generalises to a tidy closed form, For the original this is . The more cups you pull, the more lopsided the evidence: drawing near drives the expected kernel count toward zero, while leaves it largest.
The computation
The same posterior sum with the general weight reproduces across several .
def expected(N, k, M=300000):
S = Sn = F(0)
for n in range(M):
w = F(1)
for i in range(k): w *= F(1, N + n - i)
S += w; Sn += n * w
return float(Sn / S)
for N, k in [(3, 3), (5, 4), (6, 4), (5, 5)]:
print(N, k, round(expected(N, k), 4)) # 1, 1, 1.5, 0.333 == (N-k+1)/(k-2)