Chapter 286
Can You Make An Unfair Coin Fair?
The Riddler for November 6, 2020. The Express compares two treadmill runs where pace, not speed, varies linearly, and the Classic counts the biased-coin probabilities that can simulate a fair coin within three flips.
Riddler Express
Santul runs miles twice. Run 1 holds a constant minutes per mile. Run 2 starts at minutes per mile and ends at , with his pace (minutes per mile, not speed) changing linearly in time. Which run is faster, and what are the two times?
The Riddler, FiveThirtyEight, November 6, 2020(original post)
Solution
Run 1 is immediate: minutes, exactly hours.
For Run 2, let be its total time in minutes. Pace varies linearly from to , so at time the pace is minutes per mile and the speed is its reciprocal, miles per minute. The distance must be miles: Substituting gives , so about seconds faster than Run 1’s . The pace spends more time near its slow end, but averaging the reciprocal of a linear pace (a logarithm) still edges below the constant -minute pace.
The computation
Encode the constraint: integrate the speed over , set it to miles, and solve for .
import math
run1 = 20 * 9 # 180 minutes
T = 40 / math.log(5 / 4) # solves (T/2) ln(5/4) = 20
mins, secs = int(T), round((T - int(T)) * 60)
print(run1, round(T, 3), f'{mins}:{secs:02d}') # 180 179.257 179:15
Run 2 takes minutes, edging out Run 1’s .
Riddler Classic
Von Neumann turns a biased coin (heads probability ) into a fair one. You want to simulate a fair coin in at most three flips: assign some set of three-flip outcomes to “heads” so their total probability is exactly . For how many values of is this possible?
The Riddler, FiveThirtyEight, November 6, 2020(original post)
Solution
Three flips give eight outcomes, grouped by their number of heads: (one outcome), (three), (three), (one). A simulation works when some subset of these outcomes has total probability exactly . By symmetry every achievable sum is with and , which is candidate equations. Each is a cubic (or lower) in ; collecting their roots in and removing duplicates leaves distinct values of . They include the obvious , plus and (where or , achievable already in two flips), and sixteen others. Extending to at most flips gives the counts , a sequence only recently catalogued.
The computation
Encode all subset-sum polynomials, find their roots in , and cluster numerically equal roots before counting.
import numpy as np
p, q = np.poly1d([1, 0]), np.poly1d([-1, 1]) # p and (1 - p)
roots = []
for a in range(2):
for b in range(4):
for c in range(4):
for d in range(2):
poly = a*p**3 + b*(p**2*q) + c*(p*q**2) + d*q**3 - 0.5
for r in np.roots(poly.c):
if abs(r.imag) < 1e-9 and 1e-9 < r.real < 1 - 1e-9:
roots.append(r.real)
roots.sort()
distinct = [r for i, r in enumerate(roots)
if i == 0 or r - roots[i-1] > 1e-5] # cluster near-equal roots
print(len(distinct)) # 19
Nineteen biased-coin probabilities can simulate a fair coin within three flips.