Skip to content
Vamshi Jandhyala

Books · The Fiddler: Solutions

Chapter 4

Can You Sneak Past the Rings?

A long vertical cylinder carries three narrow open rings. Each ring wraps around seven-eighths of the cylinder, leaving a gap of one-eighth. The rings sit at evenly spaced heights, and each is rotated about the cylinder’s axis independently and uniformly at random.

You want to send something straight down the outside of the cylinder without touching a ring. What is the probability that there is at least one vertical line passing through all three gaps?

The Fiddler, Zach Wissner-Gross, July 31, 2026(original post)

The official solution appears in the post of August 7, 2026, which had not been published when this chapter was written. The answers here are my own.

Solution

Measure position around the cylinder as a fraction of the circumference, so an angle is a point on a circle of circumference 11 and the whole picture lives on that circle. Write g=1/8g = 1/8 for the length of a gap. Ring ii leaves the gap Gi=[ci,  ci+g),G_i = [c_i,\; c_i + g), an arc of length gg beginning at cic_i, where c1c_1, c2c_2, c3c_3 are independent and uniform on the circle. Everything below is arithmetic modulo 11.

A vertical line sits at a single angle xx and keeps that angle all the way down. It clears the rings exactly when xx lies in all three gaps. So the question is whether the three arcs G1G_1, G2G_2, G3G_3 have a point in common.

Here is the move that makes the problem easy. Rather than ask where the common point is, ask where the arcs start. The point xx lies in [ci,ci+g)[c_i, c_i+g) precisely when cic_i lies in (xg,x](x-g,\, x], which is an arc of length gg ending at xx. Reading that for all three at once:

The three gaps share a point exactly when the three starting points c1c_1, c2c_2, c3c_3 all lie inside a single arc of length gg.

The question has turned from one about overlapping arcs into one about three random points falling close together, which is a question we can count.

So suppose the three points do lie in some arc of length gg. Going clockwise, one of them comes first, and the arc of length gg that begins at that point contains the other two. Let AiA_i be the event that cic_i is that first point, that is, that the other two points both lie in [ci,ci+g)[c_i, c_i + g). Since g<1/2g < 1/2 the three events cannot happen together: if c1c_1 and c2c_2 were each first, each would lie within gg of the other going clockwise, and the two arcs of length gg would have to cover the whole circle, which needs 2g12g \ge 1. So the AiA_i are disjoint, and one of them must occur.

Each AiA_i is easy. Given where cic_i falls, the other two points land independently in a prescribed arc of length gg, each with probability gg, so Pr(Ai)=g2\Pr(A_i) = g^2. Adding the three disjoint cases, Pr(a vertical line exists)=3g2.\Pr(\text{a vertical line exists}) = 3g^{2}. With g=1/8g = 1/8 this is  364=0.046875(4.6875%). \boxed{\ \frac{3}{64} = 0.046875 \quad (4.6875\%).\ }

It is worth seeing why the answer is so small. Two gaps overlap somewhere with probability 2g=1/42g = 1/4 already, and asking a third gap to meet that overlap costs most of what is left. Each ring after the first is close to an independent one-in-eight demand.

The computation

The check must not evaluate 3g23g^2, which would only confirm the counting. Instead, place the three rings at random and look for a line.

The search needs no grid. If the three arcs do share a point, then the set of angles they share is itself an arc, and its left-hand end is the start of one of the three gaps. So it is enough to test three candidate angles, namely c1c_1, c2c_2 and c3c_3, and ask whether any one of them lies in all three gaps.

  1. Draw c1c_1, c2c_2, c3c_3 independently and uniformly on [0,1)[0,1).

  2. For each of the three candidate angles ckc_k, test whether it lies in every gap, that is, whether (ckci)mod1<g(c_k - c_i) \bmod 1 < g for i=1,2,3i = 1,2,3.

  3. Record a success if any candidate passes, and repeat.

import numpy as np

rng = np.random.default_rng(20260801)
N, g = 5_000_000, 1/8
c = rng.random((3, N))                      # where each gap starts

def in_gap(theta, left):                    # is this angle inside that gap?
    return ((theta - left) % 1.0) < g

hit = np.zeros(N, bool)
for k in range(3):                          # a shared arc starts at some gap's edge
    theta = c[k]
    hit |= in_gap(theta, c[0]) & in_gap(theta, c[1]) & in_gap(theta, c[2])

print(f"vertical line : {hit.mean():.6f}   (3/64 = {3/64:.6f})")
# vertical line : 0.047017   (3/64 = 0.046875)

Five million cylinders give 0.0470170.047017 against the derived 3/64=0.0468753/64 = 0.046875.

Extra Credit

Instead of a vertical line, any helix down the surface of the cylinder is allowed. What is the probability that there is at least one helix passing through all three gaps?

Solution

Cut the cylinder down its length and unroll it. Angles become horizontal positions, height becomes the vertical axis, and the three rings become three horizontal lines. A helix has constant pitch, so on the unrolled sheet it is a straight line. The extra credit is therefore asking for a straight line through the three gaps rather than a vertical one, and a vertical line is just the special case of zero slope.

The rings are evenly spaced, so a straight line crosses them at three angles in arithmetic progression: some φ\varphi, then φ+t\varphi + t, then φ+2t\varphi + 2t, where tt is the angle the helix turns through between one ring and the next. The pitch is unrestricted, so tt can be anything.

Now think about where in each gap the line passes. Write mim_i for the middle of gap ii, and let the line cross ring ii at mi+eim_i + e_i. Staying inside the gap means eig/2|e_i| \le g/2. Being an arithmetic progression means the middle term is the average of the outer two, that is (m2+e2)(m1+e1)=(m3+e3)(m2+e2),(m_2 + e_2) - (m_1 + e_1) = (m_3 + e_3) - (m_2 + e_2), which rearranges to m12m2+m3D  +  (e12e2+e3)  =  0.\underbrace{m_1 - 2m_2 + m_3}_{\textstyle D} \;+\; (e_1 - 2e_2 + e_3) \;=\; 0 . The quantity DD is the second difference of the three gap positions. It measures how far the gaps are from being equally spaced around the cylinder, and it is fixed once the rings are placed. The other term is ours to choose.

So a helix exists exactly when we can choose the three offsets to cancel DD. Each eie_i ranges over [g/2,g/2][-g/2,\, g/2], and the coefficients 1,2,11, -2, 1 have absolute values summing to 44, so e12e2+e3e_1 - 2e_2 + e_3 sweeps the whole interval [2g,2g][-2g,\, 2g] and nothing more. The condition is therefore D2g(mod1),|D| \le 2g \pmod 1 , where D|D| means the distance from DD to the nearest multiple of 11.

The last step is to see how DD is distributed. The gap positions are independent and uniform, so for any fixed values of m1m_1 and m2m_2 the quantity D=m12m2+m3D = m_1 - 2m_2 + m_3 is uniform on the circle, being a uniform m3m_3 shifted by a constant. Hence DD is uniform, and the condition D2g|D| \le 2g picks out an arc of length 4g4g: Pr(a helix exists)=4g.\Pr(\text{a helix exists}) = 4g . With g=1/8g = 1/8,  12=0.5(50%). \boxed{\ \frac{1}{2} = 0.5 \quad (50\%).\ }

The jump from one chance in twenty-one to one chance in two is the whole interest of the puzzle. A vertical line demands that the three gaps be nearly aligned, which is two conditions. A helix demands only that they be nearly equally spaced, which is one. Relaxing from lines to helices does not widen the gaps; it removes a constraint.

The computation

Again the check must not use D2g|D| \le 2g. Search instead over the helix itself: sweep the pitch tt across its whole range, and for each pitch test candidate start angles the same way as before, pulling each gap’s edge back to the first ring.

import numpy as np

rng = np.random.default_rng(20260801)
M, NT, g = 60_000, 6_000, 1/8
c = rng.random((3, M))
ts = np.linspace(0, 1, NT, endpoint=False)

def in_gap(theta, left):
    return ((theta - left) % 1.0) < g

hit = np.zeros(M, bool)
for chunk in np.array_split(np.arange(NT), 60):
    t = ts[chunk][:, None]
    for k in range(3):                      # candidate starts, pulled back to ring 1
        phi = c[k][None, :] - k * t
        hit |= (in_gap(phi, c[0][None, :])
                & in_gap(phi + t, c[1][None, :])
                & in_gap(phi + 2 * t, c[2][None, :])).any(axis=0)

print(f"helix : {hit.mean():.6f}   (1/2 = 0.500000)")
# helix : 0.498267   (1/2 = 0.500000)

Sixty thousand cylinders, each searched over six thousand pitches, give 0.4982670.498267 against the derived 1/21/2.

A search that answers yes too readily would report a half whatever the gaps were, so it is worth confirming that the same code can say something else. Rerun it with g=0.02g = 0.02 and it returns 0.0800330.080033, against 4g=0.084g = 0.08.

Interactive: turn the rings, find a way down

path blocked second difference 0.000 clear when at most 0.250

path allowed
turn ring
camera
rings
Each ring covers seven eighths of the cylinder, so each gap is one eighth wide. A vertical line has to find one angle inside all three gaps at once, which happens with probability 3/64. A helix only has to meet the three gaps at angles in arithmetic progression, so it succeeds whenever the second difference of the gap positions is at most two gap widths, with probability 1/2. Turn the rings until the readout goes green under each rule and the difference between the two becomes hard to miss.