Skip to content
Vamshi Jandhyala

Books · The Riddler

Chapter 2

Can You Knock Down The Last Bowling Pin?

Magritte the bowler is back! This time, he is competing head-to-head against fellow bowler Fosse. However, rather than knocking down 1010 pins arranged in a triangular formation, they are trying to knock down N2N^2 pins (where NN is some very, very large number) arranged in a rhombus, as shown below:

When Magritte rolls, he always knocks down the topmost pin. Then, if any pin gets knocked down, it has a 5050 percent chance of knocking down either of the two pins directly behind it, independently of each other. (If there is only one pin directly behind it, then it too has a 5050 percent chance of being knocked over.)

Fosse is a stronger bowler than Magritte. Like Magritte, she always knocks down the topmost pin. But each pin that’s knocked down then has a 7070 percent chance (rather than Magritte’s 5050 percent) of knocking down any of the pins directly behind it.

What are Magritte’s and Fosse’s respective probabilities of knocking down the bottommost pin in the rhombus formation?

Solution

This is a directed bond percolation problem on the rhombic lattice, and the percolation probability for it has no known closed form. Each knocked pin wets each pin directly behind it with probability pp (the bond is “open”), and the question is whether the wet cluster from the top pin reaches the lone bottom pin.

What governs the outcome is the directed-percolation threshold pcp_c of this lattice, around 0.60.6. Magritte plays at p=0.5p=0.5, comfortably below threshold: the wet front dies out after finitely many rows, so for a very large rhombus the bottom pin is essentially never reached, a probability that tends to 00. Fosse plays at p=0.7p=0.7, above threshold: the wet front survives with positive probability and can span the whole rhombus, but even then the single bottom pin is reached only sometimes. A large-lattice Monte Carlo estimate gives PMagritte0,PFosse0.58.P_{\text{Magritte}} \approx \boxed{0}, \qquad P_{\text{Fosse}} \approx \boxed{0.58}. (Fosse’s value is a finite-size simulation estimate of an unsolved quantity, not an exact figure.)

The computation

Propagate the wet front row by row down the rhombus, vectorised over many parallel rolls. Expanding rows (top half) send each wet pin to its two children through independent open bonds; contracting rows (bottom half) collect each child from its two parents. The fraction of rolls whose front reaches the final single pin is the answer.

import numpy as np
def reach_bottom(p, n, runs, seed=0):
    rng = np.random.default_rng(seed)
    sizes = list(range(1, n+1)) + list(range(n-1, 0, -1))   # rhombus row sizes
    wet = np.ones((runs, 1), bool)               # topmost pin always knocked down
    for r in range(len(sizes) - 1):
        s, s2 = sizes[r], sizes[r+1]
        if s2 > s:                               # expanding: parent j -> children j, j+1
            nxt = np.zeros((runs, s2), bool)
            nxt[:, :s] |= wet & (rng.random((runs, s)) < p)
            nxt[:, 1:] |= wet & (rng.random((runs, s)) < p)
        else:                                    # contracting: child m <- parents m, m+1
            nxt = (wet[:, :s2] & (rng.random((runs, s2)) < p)) | \
                  (wet[:, 1:]  & (rng.random((runs, s2)) < p))
        wet = nxt
    return wet[:, 0].mean()
print(round(reach_bottom(0.7, 500, 5000), 3))    # Fosse ~0.58
print(round(reach_bottom(0.5, 500, 5000), 4))    # Magritte ~0