Chapter 68
Can You Win The Penalty Shootout?
Riddler Express
A -inch stick is bitten at a uniformly random point by Fatch, and painted black above the bite, white below. Fetch and Fitch then each bite a uniformly random point. What is the probability that Fetch and Fitch bite the same colour?
Solution
Fetch and Fitch share a colour exactly when their two bites fall on the same side of Fatch’s mark, both above it or both below. The three bite positions are independent and uniform, so all orderings of the three marks are equally likely. Fetch and Fitch land on the same side precisely when Fatch’s mark is not between them, that is, when Fatch is the lowest or the highest of the three. Fatch is the middle mark in of the orderings and an outer mark in the other , so
The computation
Drop three uniform bites and count how often the two later bites share a side of the first.
import numpy as np
rng = np.random.default_rng(0)
fa, fe, fi = (rng.random(5_000_000) for _ in range(3))
same = ((fe < fa) & (fi < fa)) | ((fe > fa) & (fi > fa))
print(same.mean()) # ~0.667 = 2/3
Riddler Classic
In a penalty shootout each player scores with probability . Teams alternate over five rounds, stopping early once the result is mathematically settled; if level after five rounds they go to sudden death (a round each until one scores and the other misses). How many shots are taken on average?
Solution
The shootout is a small Markov process: after each kick, check whether the trailing team can still catch up within the five rounds, and stop the moment it cannot. Two pieces make it tractable. The five-round phase is a finite tree of kicks, each scored with probability , that we can average exactly. Sudden death, reached only on a – tie, is a sequence of two-kick rounds, each decisive (one scores, one misses) with probability , so it adds an expected shots whenever it occurs.
Combining the regulation tree with that sudden-death tail gives the exact expectation So a shootout runs a little past the nominal ten kicks of five rounds each, the extra coming from the cases that drag into sudden death, partly offset by the ones that end early.
The computation
Recurse over the shootout state (kicks taken and goals for each side). Stop when the outcome is decided, fold in the closed-form sudden-death cost at a – tie, and average exactly with fractions.
from fractions import Fraction as F
from functools import lru_cache
p = F(7, 10); q = 1 - p
def decided(t1, t2, g1, g2):
return max(5 - t1, 0) + g1 < g2 or max(5 - t2, t1 - t2) + g2 < g1
@lru_cache(None)
def E(t1, t2, g1, g2):
if decided(t1, t2, g1, g2): return F(0)
if t1 == 5 and t2 == 5:
return F(0) if g1 != g2 else 1 / (p * q) # sudden-death tail
if t1 == t2: # team 1 kicks
return 1 + p * E(t1+1, t2, g1+1, g2) + q * E(t1+1, t2, g1, g2)
return 1 + p * E(t1, t2+1, g1, g2+1) + q * E(t1, t2+1, g1, g2)
print(E(0, 0, 0, 0), float(E(0, 0, 0, 0))) # 549682873/52500000, 10.47