Skip to content
Vamshi Jandhyala

Books · The Riddler

Chapter 87

Can You Make The Fidget Spinner Go Backwards?

A thousand players each hold a random 4×44\times 4 board of 1616 distinct pictures drawn from a 5454-card deck. Cards are drawn one at a time, and a player wins on completing any full row, full column, the four corners, or any 2×22\times 2 block (1818 winning patterns). After four cards there is no winner. What is the probability that exactly one player wins when the fifth card is drawn?

Solution

This is a conditional probability tied to the shared sequence of drawn cards. Draw five cards; the first four leave no winner, and we ask how often the fifth card produces exactly one. Each of the thousand boards is an independent random 1616-subset, so given the five drawn cards a board wins only if some one of its 1818 patterns is fully covered. The dependence on the common draw and the size of the field (10001000 boards) makes a clean formula awkward, so the honest tool is direct simulation: deal the five cards, discard any deal in which someone already won by the fourth, and among the rest measure how often the fifth card crowns precisely one winner. The result is 0.18.\boxed{\approx 0.18.} A single winner on the fifth card is the most common interesting outcome; ties (two or more winning together) and no-winner are the remaining cases.

The computation

Deal five cards to a thousand random boards, mark each board’s win status by testing all 1818 patterns against the drawn set, keep only deals with no winner after four cards, and record how often exactly one board wins after five.

import numpy as np
rng = np.random.default_rng(0)
patterns = np.array([[0,1,2,3],[4,5,6,7],[8,9,10,11],[12,13,14,15],
    [0,4,8,12],[1,5,9,13],[2,6,10,14],[3,7,11,15],[0,3,12,15],
    [0,1,4,5],[1,2,5,6],[2,3,6,7],[4,5,8,9],[5,6,9,10],
    [6,7,10,11],[8,9,12,13],[9,10,13,14],[10,11,14,15]])
def trial(players=1000):
    boards = np.argsort(rng.random((players, 54)), axis=1)[:, :16]
    draw = rng.permutation(54)[:5]
    def winners(k):
        marked = np.isin(boards, draw[:k])          # which board cells are drawn
        return sum(marked[:, p].all(1) for p in patterns) > 0
    if winners(4).any(): return None                # someone already won
    return int(winners(5).sum())
res = [r for _ in range(40_000) if (r := trial()) is not None]
print(np.mean([w == 1 for w in res]))               # ~0.18