Books · The Fiddler: Solutions
Chapter 29
Can You Irrigate the Garden?
A circular garden has radius furlong. Your assistant picks two random points on the boundary and runs a straight hose between them. On average, how far is the centre of the garden from the nearest part of the hose?
The Fiddler, Zach Wissner-Gross, November 14, 2025(original post)
Solution
The hose is a chord, and the centre’s nearest point on it is the foot of the perpendicular, always on the chord. A chord whose endpoints subtend a central angle lies at distance from the centre. The angle between two independent uniform boundary points is itself uniform; writing for the (uniform) angular gap on , the distance is , so
The computation
Lay random hoses: two uniform boundary points make a chord, and the centre’s nearest point on it is the foot of the perpendicular (clamped to the segment). Average that distance over millions of chords.
import numpy as np
rng = np.random.default_rng(0); M = 4_000_000
t1, t2 = rng.uniform(0, 2*np.pi, M), rng.uniform(0, 2*np.pi, M)
A = np.c_[np.cos(t1), np.sin(t1)]; B = np.c_[np.cos(t2), np.sin(t2)]
AB = B - A; t = np.clip(-np.sum(A*AB, 1)/np.sum(AB*AB, 1), 0, 1)
print(round(np.linalg.norm(A + t[:, None]*AB, axis=1).mean(), 5)) # ~0.6366 = 2/pi
Extra Credit
Now you plant a second peach tree at a uniformly random point inside the garden. On average, how far is that point from the nearest part of the hose?
Solution
A random interior point is typically farther from a random chord than the centre is, since it can sit well off to one side. The foot of the perpendicular may now fall beyond an endpoint, so the nearest point is sometimes an endpoint of the hose. Averaging over both the random chord and the random interior point, (The source’s value is behind its paywall; this is my own, by simulation.)
The computation
The same chords, but now also draw a uniform interior point (radius for the right density) and measure its distance to the nearest part of the hose, clamping the foot of the perpendicular to the segment.
rng = np.random.default_rng(1); M = 4_000_000
t1, t2 = rng.uniform(0, 2*np.pi, M), rng.uniform(0, 2*np.pi, M)
A = np.c_[np.cos(t1), np.sin(t1)]; B = np.c_[np.cos(t2), np.sin(t2)]
r = np.sqrt(rng.uniform(0, 1, M)); a = rng.uniform(0, 2*np.pi, M)
P = np.c_[r*np.cos(a), r*np.sin(a)]
AB = B - A; t = np.clip(np.sum((P - A)*AB, 1)/np.sum(AB*AB, 1), 0, 1)
print(round(np.linalg.norm(P - (A + t[:, None]*AB), axis=1).mean(), 4)) # ~0.742