Chapter 256
Can You Flip Your Way To Victory?
The Riddler for February 21, 2020. The Express hunts for the temperature whose Fahrenheit and Celsius readings are digit-reversals of each other. The Classic is a coin-flipping game where you pick, flip by flip, between a low-stakes and a high-stakes coin and try to end with a positive score.
Riddler Express
Toggling a thermometer between Fahrenheit and Celsius, you notice the rounded reading’s two digits have simply swapped: F is C, for instance. But the temperature that warm, sunny day was not F. What was it?
The Riddler, FiveThirtyEight, February 21, 2020(original post)
Solution
A warm day means a two-digit Fahrenheit reading , with tens digit and ones digit . Its Celsius value is , and we want , rounded, to read (the digits swapped). Ignoring the rounding for a moment, Step through the digits to and round the resulting :
gives : that is F C, written “,” a leading zero rather than a genuine swap (and hardly a warm day).
gives : that is F C, the example we are told to exclude.
gives : that is F, and C. The digits swap, and it is genuinely warm.
gives , impossible for a single digit.
So the temperature was
The computation
Encode the condition directly: for every two-digit Fahrenheit reading, round its Celsius value and keep those whose digits are the reverse.
def rev(n): return (n % 10)*10 + n // 10
matches = [F for F in range(10, 100) if round((F - 32)*5/9) == rev(F)]
print(matches) # [40, 61, 82]
The three matches are (the degenerate “” with a leading zero), (the excluded example) and , leaving F as the answer.
Riddler Classic
You have two fair coins. Coin A is worth point (heads , tails ); coin B is worth . You make flips, choosing which coin to flip each time knowing all earlier outcomes, and you win if your final score is strictly positive (any positive total is as good as any other). Optimising your strategy, what percentage of games do you win? Extra credit: what if coin A comes up heads with probability (coin B still fair)?
The Riddler, FiveThirtyEight, February 21, 2020(original post)
Solution
Work backwards. Let be your best winning probability with score and flips left. With no flips left you win exactly when . With left you pick whichever coin gives the larger chance: where the two options are Solving this from up to and reading off gives (precisely ). It can exceed even though each coin is fair, because the policy is asymmetric: when your score is positive you flip the low-variance coin A to protect the lead, and when it is zero or negative you flip the high-variance coin B to give yourself a chance. Like running out the clock with a lead but speeding up when behind, this skews you toward small positive finishes and away from large negative ones, while keeping the average score at . As the number of flips grows the winning probability rises toward .
For the extra credit, the same recursion works with coin A landing heads with probability (only the coin-A line changes to ). The winning probability is then a nonlinear, S-shaped function of : near it sits close to the value, it climbs to a guaranteed win as (just keep flipping A), and it falls away as (you lean on B and cash in coin A only once its near-certain tails can no longer hurt you).
The computation
Encode the dynamic program: as an array over scores, stepped back times, taking the better coin at each score. The same routine, parameterised by , answers the extra credit.
def win_prob(pA, N=100):
off = 2*N
V = [1.0 if s - off > 0 else 0.0 for s in range(4*N + 1)] # k = 0
for _ in range(N):
nV = [0.0]*(4*N + 1)
for s in range(4*N + 1):
a = pA*V[min(4*N, s+1)] + (1 - pA)*V[max(0, s-1)] # coin A
b = 0.5*V[min(4*N, s+2)] + 0.5*V[max(0, s-2)] # coin B
nV[s] = a if a > b else b
V = nV
return V[off]
print(round(win_prob(0.5), 4)) # 0.6403
for p in (0.4, 0.5, 0.6):
print(p, round(win_prob(p), 4)) # 0.4 0.5357 / 0.5 0.6403 / 0.6 0.9797
The fair-coin game is won about of the time, and the extra-credit values trace the S-shaped rise in .