Skip to content
Vamshi Jandhyala

Books · The Fiddler: Solutions

Chapter 11

Can You Number the Number Cubes?

You have four number cubes, and each of the 2424 faces can show any one digit from 00 to 99. You form a number by picking three faces on three distinct cubes and lining them up, reading every value as three digits with leading zeros, so 11 is 0010\,0\,1. A 66 may be turned upside down to serve as a 99, and vice versa, but no other digits are interchangeable. Choosing the faces wisely, what is the largest NN such that every whole number from 11 to NN can be formed?

The Fiddler, Zach Wissner-Gross, April 10, 2026(original post)

Solution

Forming a number means matching its three digits to three distinct cubes, each carrying the required digit, so a number is reachable exactly when its digits have a system of distinct representatives among the cubes. Treat 66 and 99 as one symbol, leaving nine symbols in all; an optimal cube carries six distinct symbols.

The maximum is N=776.N = \boxed{776}. The face budget makes this sharp. The triples 111,,555111,\dots,555 and 666666 each demand their digit on three cubes (six symbols ×\times three cubes =18=18 faces); then 100100, 7777, 8888 each force a symbol onto two cubes (66 faces). That is 18+6=2418+6=24 faces, exactly the four cubes. Reaching 777777 would need a third cube bearing a 77, with no free face for it. One design that attains 776776 is {0,1,3,4,5,6~},{0,2,3,4,7,6~},{1,2,3,5,8,6~},{1,2,4,5,7,8},\begin{gathered} \{0,1,3,4,5,\tilde6\},\quad \{0,2,3,4,7,\tilde6\},\\ \{1,2,3,5,8,\tilde6\},\quad \{1,2,4,5,7,8\}, \end{gathered} writing 6~\tilde6 for the shared 6/96/9 symbol.

The computation

Pose it as a constraint problem: each cube carries six of the nine symbols, and for every target 1kM1\le k\le M the three digits must map to three distinct cubes that each carry the needed symbol. A CP-SAT solver finds a design for M=776M=776 and proves none exists for 777777.

from ortools.sat.python import cp_model
IDX = {0:0,1:1,2:2,3:3,4:4,5:5,6:6,9:6,7:7,8:8}   # 6 and 9 share symbol 6
def reachable(M):                  # can one design form every 1..M?
    m = cp_model.CpModel()
    has = {(c,s): m.NewBoolVar("") for c in range(4) for s in range(9)}
    for c in range(4):
        m.Add(sum(has[c,s] for s in range(9)) == 6)
    for k in range(1, M+1):
        r = [IDX[k//100%10], IDX[k//10%10], IDX[k%10]]
        a = {(p,c): m.NewBoolVar("") for p in range(3) for c in range(4)}
        for p in range(3):
            m.Add(sum(a[p,c] for c in range(4)) == 1)
            for c in range(4): m.Add(a[p,c] <= has[c, r[p]])
        for c in range(4): m.Add(sum(a[p,c] for p in range(3)) <= 1)
    return cp_model.CpSolver().Solve(m) in (cp_model.OPTIMAL, cp_model.FEASIBLE)
print(reachable(776), reachable(777))     # True False  ->  max N = 776

Extra Credit

How many distinct ways are there to fill the four cubes so as to attain this greatest NN? Cubes are unordered, the order of faces on a cube does not matter, and 66 and 99 count as the same digit.

Solution

Every optimal design is forced into the same shape: the symbols 1,2,3,4,5,6~1,2,3,4,5,\tilde6 appear on exactly three cubes each and 0,7,80,7,8 on exactly two, using all 2424 faces. Enumerating the four six-symbol cubes under that budget and keeping those that really do form all of 11 to 776776, the number of distinct designs is 855.\boxed{855}. (The source’s extra-credit answer is behind its paywall; this count is my own, from the enumeration below.)

The computation

Enumerate every unordered choice of four six-symbol cubes (as bitmasks), keep those meeting the symbol budget, and accept a design only if every required digit-triple up to 776776 has a system of distinct representatives across the cubes.

import itertools as it
mult = {tuple(sorted(IDX[d] for d in (k//100%10, k//10%10, k%10)))
        for k in range(1, 777)}
masks = [sum(1 << s for s in S) for S in it.combinations(range(9), 6)]
def sdr(d, r):                     # distinct cubes for the three digits r
    def go(i, used):
        if i == 3: return True
        return any(not used >> c & 1 and d[c] >> r[i] & 1
                   and go(i+1, used | 1 << c) for c in range(4))
    return go(0, 0)
count = 0
for combo in it.combinations_with_replacement(range(len(masks)), 4):
    d = [masks[i] for i in combo]
    if all(sum(x >> s & 1 for x in d) >= 3 for s in (1,2,3,4,5,6)) \
       and all(sdr(d, r) for r in mult):
        count += 1
print(count)                       # 855