Chapter 38
Can You Find A Matching Pair Of Socks?
The Riddler for December 20, 2019. The Express is an office-vote puzzle: from three rounded-down percentages, reconstruct the smallest possible office. The Classic asks, on average, how many loose socks you must pull from a drawer to get a matching pair.
Riddler Express
You record the share of the vote each party theme received, but in a hurry you keep only the digits before the decimal point (so , and are all written “”). The winner came out at , second place at , and third at (people evidently voted more than once). Based on these recorded percentages, what is the minimum number of people who could work in the office? Extra credit: what is the greatest number of people the office cannot have?
The Riddler, FiveThirtyEight, December 20, 2019(original post)
Solution
Recording “” for a count of votes out of people means , that is, the half-open interval contains a whole number . The same goes for and . (Since people cheated and voted repeatedly, the counts are just nonnegative integers, not tied to .) Each such interval has length .
That length is the whole story. Once every one of these intervals is at least wide and so always contains an integer, making all three percentages achievable. So only can fail, and both a smallest working and a largest failing exist; find them by checking the intervals.
Searching upward, the first for which all three intervals catch an integer is realised by , and .
For the extra credit, search downward from . The largest office size for which some percentage is unreachable is between and no count yields . Every size and above works, in keeping with the guarantee.
The computation
Encode the rule directly: a percentage is attainable for office size when some integer count has . Find the smallest that attains all of , and the largest that fails at least one.
import math
def attainable(N, p):
return any(math.floor(100*a/N) == p for a in range(0, 3*N + 1))
def works(N):
return all(attainable(N, p) for p in (73, 58, 32))
min_N = next(N for N in range(1, 500) if works(N))
max_fail = max(N for N in range(1, 100) if not works(N))
print(min_N, max_fail) # 34 88
The smallest possible office is people, and the greatest impossible size is , as boxed.
Riddler Classic
I have 10 pairs of distinct socks loose in a drawer. In the dark I pull socks out one at a time until I have a matching pair among those removed. On average, how many socks do I pull out to get my first matching pair? Extra credit: what if I have pairs?
The Riddler, FiveThirtyEight, December 20, 2019(original post)
Solution
Suppose the first socks pulled all came from different pairs, so no match yet. Among the socks still in the drawer, exactly are the partners of the ones already out (drawing any of them makes a pair), and the other come from untouched pairs. So the next sock avoids a match with probability Let be the draw on which the first pair appears. Getting through draws with no match has probability , and summing the survival probabilities, For this evaluates to So even though the pigeonhole guarantee is socks, on average fewer than six suffice.
For the extra credit, the early factors behave like , so and the sum is well approximated by a Gaussian integral, giving For that estimate is , already close to the exact .
The computation
Evaluate the exact product-sum, and confirm it by pulling socks at random until a pair appears.
from fractions import Fraction as F
import numpy as np
def expected(N):
E = F(0); p = F(1)
for k in range(N + 1):
E += p
p *= F(2*N - 2*k, 2*N - k) # survival for next draw
return E
print(expected(10), float(expected(10))) # 262144/46189 ~ 5.676
rng = np.random.default_rng(0); runs = 1_000_000; total = 0
for _ in range(runs):
drawer = rng.permutation([i for i in range(10) for _ in range(2)])
seen = set()
for n, s in enumerate(drawer, 1):
if s in seen:
total += n; break
seen.add(s)
print(total / runs) # ~5.68