Chapter 69
Can You Solve This Astronomical Enigma?
Riddler Express
Two cicada broods with periods and years have just emerged together. They interfere whenever one brood emerges exactly one year after the other (a multiple of and a multiple of differing by ). With and coprime and both at most , what is the longest a pair can go before its first interference?
Solution
Interference first happens in the earliest year for which a multiple of and a multiple of are one year apart, . Because and are coprime, such multiples always exist, and we want the pair that pushes this first collision as late as possible. Scanning all coprime pairs up to , the winner is , : so the first interference is in year The two largest coprime periods available are also nearly equal, which forces their multiples to take the longest to drift to within a single year of each other.
The computation
For each coprime pair, find the earliest year where a multiple of sits one off a multiple of , and take the largest such year.
from math import gcd
def first_interference(a, b):
return min(max(x, y) for x in range(0, a*b + 1, a)
for y in range(0, a*b + 1, b) if abs(x - y) == 1)
pairs = [(a, b) for a in range(1, 20) for b in range(a, 21) if gcd(a, b) == 1]
print(max((first_interference(a, b), a, b) for a, b in pairs)) # (153, 17, 19)
Riddler Classic
Three planets orbit a star in circles: planet at radius with period years, at radius with period , at radius with period . They are collinear right now. When are the three planets next collinear (the star need not be on the line)?
Solution
Planet sits at with . Three points are collinear exactly when the signed area of their triangle vanishes, that is when With this expands to At all three sit on the same axis, so that is one solution; the next positive root is
The computation
Track the three planets’ actual positions and scan for the first time after when the signed area of their triangle changes sign.
import numpy as np
rw = [(3, 2*np.pi/3), (4, np.pi/2), (5, 2*np.pi/5)]
def area(t):
(x1, y1), (x2, y2), (x3, y3) = [(r*np.cos(w*t), r*np.sin(w*t)) for r, w in rw]
return (x2 - x1)*(y3 - y1) - (x3 - x1)*(y2 - y1)
ts = np.linspace(1e-5, 9, 4_000_000)
v = area(ts)
print(ts[:-1][np.diff(np.sign(v)) != 0][0]) # ~7.767