Skip to content
Vamshi Jandhyala

Books · The Riddler

Chapter 91

Can You Win The Riddler Football Playoff?

Riddler Express

Four teams in a group each play the other three once (66 matches), scoring 33 for a win, 11 for a draw, 00 for a loss. After the group, all four teams have different point totals: A>B>C>DA > B > C > D. Find every possible quadruple (A,B,C,D)(A, B, C, D).

Solution

Each of the 66 matches independently ends in a home win, away win, or draw, so there are 36=7293^6 = 729 outcome patterns. Tallying each team’s points, sorting, and keeping only the patterns with four distinct totals leaves exactly thirteen quadruples: (5,4,3,2), (6,5,4,1), (7,4,3,1), (7,4,3,2), (7,5,2,1),(7,5,3,1), (7,5,4,0), (7,6,2,1), (7,6,3,1), (7,6,4,0),(9,4,2,1), (9,4,3,1), (9,6,3,0).\boxed{\begin{aligned} &(5,4,3,2),\ (6,5,4,1),\ (7,4,3,1),\ (7,4,3,2),\ (7,5,2,1),\\ &(7,5,3,1),\ (7,5,4,0),\ (7,6,2,1),\ (7,6,3,1),\ (7,6,4,0),\\ &(9,4,2,1),\ (9,4,3,1),\ (9,6,3,0). \end{aligned}} The total points across the group range from 1212 (all matches decisive) to 1818 minus the draws, which is why the four-way splits cluster the way they do.

The computation

For each of the six matches, enumerate its three outcomes, take the product over all matches, and collect the sorted totals that are strictly decreasing.

import numpy as np
from itertools import combinations, product
def outcomes(i, j):                            # three results of match i vs j
    res = []
    for si, sj in [(3, 0), (0, 3), (1, 1)]:
        v = np.zeros(4); v[i], v[j] = si, sj; res.append(v)
    return res
quads = set()
for combo in product(*[outcomes(i, j) for i, j in combinations(range(4), 2)]):
    a, b, c, d = sorted(sum(combo), reverse=True)
    if a > b > c > d: quads.add((a, b, c, d))
print(len(quads))                              # 13

Riddler Classic

Four playoff teams get independent uniform qualities in [0,1][0,1]. Team aa beats team bb with probability a/(a+b)a/(a+b). The top seed plays the bottom seed, the middle two play each other, and the winners meet in the final. On average, what is the champion’s quality?

Solution

The bracket is fixed by the seeding: the highest quality plays the lowest, the middle two play each other, and the two winners meet. Quality helps but never guarantees a win, since even the best team loses with positive probability at each round. Averaging the champion’s quality over random draws and random match outcomes gives 0.674.\boxed{\approx 0.674.} That sits well above the average quality 0.50.5 of a random team and above the 0.60.6 expected of the strongest of four, because the playoff structure filters toward the better teams while still letting upsets through.

The computation

Draw four qualities, seed them, play the two semifinals and the final with the a/(a+b)a/(a+b) rule, and average the winner’s quality.

import numpy as np
rng = np.random.default_rng(0)
N = 5_000_000
q = np.sort(rng.random((N, 4)), axis=1)        # a < b < c < d
def beat(p, r):                                # p wins vs r w.p. p/(p+r)
    return np.where(rng.random(N) < p / (p + r), p, r)
champ = beat(beat(q[:, 3], q[:, 0]), beat(q[:, 2], q[:, 1]))
print(champ.mean())                            # ~0.674