Books · The Fiddler: Solutions
Chapter 81
How Many Dice Can You Roll the Same?
In the dice game TENZI, each player rolls a handful of dice, then keeps re-rolling, racing to make them all show the same number. Consider a stripped-down version, THREEZI, with three dice. You roll all three, then set aside every die showing whichever value appears most often. On average, how many dice do you set aside after that first roll?
The Fiddler, Zach Wissner-Gross, October 4, 2024(original post)
Solution
Of the equally likely rolls of three dice, sort by the largest matching group. All three equal happens in ways and sets aside . Exactly two equal happens in ways (the repeated value, which two dice show it, the odd value) and sets aside . All three different happens in ways and sets aside . The average is dice.
The computation
With only rolls, enumerate them and average the size of the most common face.
from fractions import Fraction as F
from itertools import product
from collections import Counter
tot = put = 0
for roll in product(range(6), repeat=3):
tot += 1; put += max(Counter(roll).values()) # set aside the most common value
print(F(put, tot)) # 53/36
Extra Credit
Now play the real game with ten dice. On average, how many do you set aside after rolling all ten (and what about dice)?
Solution
With ten dice the same idea holds, but “most often” now ranges over the ways ten dice split across six faces. Averaging the largest group size over every such split, weighted by its multinomial count, gives There is no tidy closed form in : the expectation grows roughly like plus a fluctuation, since for large the most common face holds a little more than a sixth of the dice.
The computation
Enumerate the ways dice fall onto the six faces, weight each by its multinomial count, and average the maximum face-count.
from math import comb
def expected_max(N):
S = F(0)
def rec(faces_left, dice_left, cur_max, ways):
nonlocal S
if faces_left == 1:
S += F(ways * max(cur_max, dice_left)); return
for c in range(dice_left + 1):
rec(faces_left - 1, dice_left - c, max(cur_max, c), ways * comb(dice_left, c))
rec(6, N, 0, 1)
return S / 6 ** N
print(expected_max(10)) # 17357555/5038848 ~ 3.445