Chapter 175
Doppler Cars and Conway’s Shuffle
Riddler Express
Andrea walks north on a path beside a parkway at mph; Barry bikes south on the same path at mph. The parkway carries smooth traffic at the speed limit in both directions. Andrea counts the ratio of southbound to northbound cars passing her as to ; Barry counts the ratio for him as to . What is the speed limit?
The Riddler, FiveThirtyEight, March 2, 2018(original post)
Solution
Setup. Let be the speed limit (mph), the rate of northbound traffic flow (cars per unit time crossing any fixed point), and the rate of southbound traffic flow. Treat traffic as a continuum so that the count Andrea or Barry observes per unit time depends only on relative speeds and the flow density.
Cars per minute observed by a moving observer. A car has a fixed speed, . The rate at which northbound cars pass a stationary observer is proportional to . If the observer moves north at speed , the closing speed of northbound cars (those overtaking the observer from behind) is ; for southbound cars (those approaching head-on), the closing speed is . So an observer moving north at sees: The constant of proportionality (traffic density) cancels in the ratio. So an observer moving north at records a south-to-north ratio A southbound observer moving at speed (i.e. heading south) flips the signs: south-to-north ratio
Andrea and Barry. Andrea heads north at , observes . Barry heads south at , observes . Let be the underlying traffic ratio (unknown but the same for both). Then From the second equation, . Substitute into the first: Cross-multiplying: . Expanding, Solve: . The roots are and . The fractional one is unphysical as a parkway limit, leaving with the underlying traffic ratio .
The computation
Solve the system directly with sympy and pick the physical root.
Set up the two ratio equations in unknowns and .
Solve symbolically.
Discard the unphysical root.
from sympy import symbols, solve, Rational
V, r = symbols('V r', positive=True)
eq1 = r * (V + 3) / (V - 3) - Rational(35, 19)
eq2 = r * (V - 15) / (V + 15) - 1
sols = solve([eq1, eq2], [V, r], dict=True)
print(sols)
The script prints the single positive- solution (the other root of the quadratic, , forces a negative and is discarded as unphysical). The boxed speed limit is mph.
Riddler Classic
You have a shuffled deck of cards numbered through . Read the first card, say it is , then reverse the order of the first cards. Repeat until the first card reads . The number of reversals depends on the deal. What is the largest number of reversals you might have to do? What order are the cards in before you start shuffling the maximum-reversal deck? Extra credit: what if the deck has cards?
The Riddler, FiveThirtyEight, March 2, 2018(original post)
Solution
This is John Conway’s topswops. Conway introduced this iteration in the 1970s. Two facts are easy: every deck eventually reaches the terminal state with on top (since after each reversal the position of never grows further from the top, and an invariant argument shows the process cannot cycle); and the worst-case number of reversals over all starting orders grows roughly like but exact values must be searched.
The exact maxima form OEIS sequence A000375:
So for , the answer is A maximal-reversal deal for is found by exhaustive backward breadth-first search (BFS) from the terminal state. There are several such maximal deals; computational solvers (Thad Beier’s animation, code shared by Adam Simon Chatterley, David Consiglio, and others) exhibit explicit -step starting decks.
Why backward BFS works. Forward, the step from deck with produces . Backward, a deck is a predecessor of iff there is some with and (so that ). BFS backward from all permutations whose top card is already assigns each permutation a depth equal to the number of forward steps needed to reach a terminal state; the maximum depth is .
Extra credit: . The state space has size and exhaustive search is infeasible. The best lower bound on is , established by Jarek Wroblewski during a 2011 programming contest; an unconfirmed upper-bound argument of was offered by Hector Pefo in the official Riddler write-up. The exact value is open.
The computation
Backward BFS from terminal states (permutations with ) up to depth . For small the search runs in seconds; for it is comfortable, for it needs about states and is the limit of what one machine handles in a day. We verify the table up to to give the algorithm and trust the OEIS-sequence value for .
Backward step: given and with , the predecessor is .
BFS from all permutations with until no new permutations are seen.
The deepest level reached is .
from itertools import permutations
def topswops_max(n):
# Backward BFS from terminal states (d[0] = 1) to depth T(n).
level = [p for p in permutations(range(1, n + 1)) if p[0] == 1]
seen = {p: 0 for p in level}
cur = level
depth = 0
deepest = (0, cur[0])
while cur:
depth += 1
nxt = []
for d in cur:
for k in range(2, n + 1):
if d[k - 1] == k:
pred = tuple(reversed(d[:k])) + d[k:]
if pred not in seen:
seen[pred] = depth
nxt.append(pred)
if depth > deepest[0]:
deepest = (depth, pred)
cur = nxt
return deepest[0], deepest[1]
for n in range(1, 9):
T, d = topswops_max(n)
print(f'n={n:2d} T(n)={T:2d} one maximal deal={d}')
The script prints , matching the OEIS sequence and validating the algorithm; extending it to reproduces given enough memory.