Project Euler Problem 376
Consider the following set of dice with nonstandard pips: Die A: 1 4 4 4 4 4 Die B: 2 2 2 5 5 5 Die C: 3 3 3 3 3 6 A gam
Solution
Answer: 973059630185670
Let
$$W(X,Y)=#{(x,y)\in X\times Y:x>y},$$
so for two six-sided dice $X,Y$,
$$P(X\text{ beats }Y)=\frac{W(X,Y)}{36}.$$
A nontransitive triple $(A,B,C)$ satisfies
$$W(B,A)>18,\qquad W(C,B)>18,\qquad W(A,C)>18.$$
Because ties are ignored, these three inequalities are equivalent to the cyclic dominance condition.
1. Encoding the dice
Instead of storing the six faces explicitly, encode each die by multiplicities.
For $1\le v\le N$, let
$$a_v,b_v,c_v\in{0,\dots,6}$$
be the number of occurrences of value $v$ on dice $A,B,C$, respectively.
They satisfy
$$\sum_{v=1}^N a_v=\sum_{v=1}^N b_v=\sum_{v=1}^N c_v=6.$$
Now define the dominance margins
$$M_{AB}=W(A,B)-W(B,A),$$
$$M_{BC}=W(B,C)-W(C,B),$$
$$M_{CA}=W(C,A)-W(A,C).$$
The desired condition becomes
$$M_{AB}<0,\qquad M_{BC}<0,\qquad M_{CA}<0.$$
2. Incremental transition formula
Process pip values from $1$ to $N$.
Suppose before value $v$ we have already placed:
$$A_<,\ B_<,\ C_<$$
faces on the three dice using smaller values.
When we place $a_v,b_v,c_v$ copies of value $v$, only comparisons against smaller values become newly determined.
Hence the margin updates are:
$$\Delta M_{AB}=a_v B_< - b_v A_<,$$
$$\Delta M_{BC}=b_v C_< - c_v B_<,$$
$$\Delta M_{CA}=c_v A_< - a_v C_<.$$
This is the key observation: each step depends only on the current cumulative counts, so a dynamic program is possible.
3. Dynamic programming state
Use states
$$(A_<,B_<,C_<,M_{AB},M_{BC},M_{CA})$$
with counts between $0$ and $6$, and margins between $-36$ and $36$.
For every pip value $v$, iterate over all choices
$$a_v,b_v,c_v\in{0,\dots,6}$$
that do not exceed six total faces.
This counts ordered triples $(A,B,C)$.
Finally:
- keep only states with all three margins negative,
- divide by $3$, because
$$(A,B,C), (B,C,A), (C,A,B)$$
represent the same cyclic set.
(There is no double-counting by reversal because the opposite orientation cannot also satisfy the inequalities.)
4. Python implementation
from collections import defaultdict
def count_nontransitive(N):
# state:
# (a_used, b_used, c_used, mab, mbc, mca)
dp = defaultdict(int)
dp[(0, 0, 0, 0, 0, 0)] = 1
for v in range(1, N + 1):
nxt = defaultdict(int)
for (au, bu, cu, mab, mbc, mca), ways in dp.items():
for av in range(7 - au):
for bv in range(7 - bu):
for cv in range(7 - cu):
nmab = mab + av * bu - bv * au
nmbc = mbc + bv * cu - cv * bu
nmca = mca + cv * au - av * cu
key = (
au + av,
bu + bv,
cu + cv,
nmab,
nmbc,
nmca,
)
nxt[key] += ways
dp = nxt
total = 0
for (au, bu, cu, mab, mbc, mca), ways in dp.items():
if (
au == bu == cu == 6 and
mab < 0 and
mbc < 0 and
mca < 0
):
total += ways
# quotient by cyclic rotations
return total // 3
print(count_nontransitive(7)) # 9780
print(count_nontransitive(30))
5. Verification on the sample
For $N=7$, the program returns
$$9780,$$
which matches the value given in the statement.
Running the same computation for $N=30$ gives
$$973059630185670.$$
The magnitude is reasonable because the number of six-multisets from $1$ to $30$ is already
$$\binom{35}{6}=1,623,160,$$
so the number of cyclically nontransitive triples is naturally enormous.
Therefore the final result is:
Answer: 973059630185670