Chapter 98
Will The Dog Catch The Duck?
A duck paddles in a perfectly circular pond and a dog prowls the bank. The dog cannot swim and the duck cannot take flight from the water, but the duck can fly to safety the instant it reaches shore, provided the dog is not there. Both are perfect strategists and can change direction instantly without losing speed. The duck starts at the centre, the dog somewhere on the edge. How many times faster than the duck must the dog be able to run so that the duck can never escape?
The Riddler, FiveThirtyEight(original post)
Solution
Take the pond to have radius , the duck speed , and let the dog run at speed . The naive duck swims straight away from the dog, a distance , while the dog runs the half-circumference to meet it; that escapes only for . The duck can do far better, and the key is to notice where it can out-turn the dog.
On a circle of radius the duck’s angular speed is and the dog’s, running the rim, is . The duck turns faster than the dog exactly while . So the duck spirals out to the circle of radius and there holds itself diametrically opposite the dog: just inside it gains angle, at it exactly keeps pace. From that opposed position it makes one straight dash.
The best dash is along the tangent to the circle of radius , the line through the duck perpendicular to the radius to it. That line meets the shore at distance and the exit point lies an angle around from the duck’s radial direction (the right triangle with hypotenuse and near side ). The dog, starting opposite, must cover that exit: a half-turn plus the offset, an angle , at speed . The duck escapes when its dash is quicker, The dog catches the duck only once this fails, so the threshold is the single with equality. It has no closed form; numerically
The computation
There is no elementary solution, so locate the threshold directly: the escape condition above holds with equality exactly at the critical speed ratio. Solve that equation by bracketing the sign change of its two sides.
import numpy as np
from scipy.optimize import brentq
# escape fails when sqrt(k^2-1) reaches pi + arccos(1/k); the root is the threshold
gap = lambda k: np.sqrt(k*k - 1) - (np.pi + np.arccos(1/k))
print(round(brentq(gap, 1.5, 10), 4))
# 4.6033