Books · The Fiddler: Solutions
Chapter 48
Can You Crack the Roman Code?
A vault keypad has three buttons: “I”, “II”, and “III” (one, two, or three marks). Pressing a sequence of buttons writes their marks side by side with no separators. The display reads ( marks), and the combination is between four and ten button-presses long. How many distinct combinations could have produced it? (Same marks in a different order count as distinct.)
The Fiddler, Zach Wissner-Gross, June 27, 2025(original post)
Solution
A combination is an ordered sequence of parts from summing to : a composition of with parts of size , , or . The length constraint is automatic, since marks need at least presses and at most (all ones). So the count is the tribonacci number
The computation
Count compositions directly: the number of ways to reach marks is the sum of the ways to reach , , and marks (the last button pressed). Build that tally up from zero.
dp = [0]*11; dp[0] = 1
for i in range(1, 11): dp[i] = sum(dp[i-k] for k in (1, 2, 3) if i >= k)
print(dp[10]) # 274
Extra Credit
A second keypad has eight buttons, the Roman numerals through , and the display reads ( characters). How many distinct combinations are possible?
Solution
Now the tokens are the Roman strings , and we count the ways to cut the -character string into such tokens. A left-to-right tally (each position sums the ways from positions a matching token-length back) gives (The source’s count is paywalled; this is my own enumeration.)
The computation
Tokenise the actual display string: walk left to right, and at each position add up the ways to have arrived from every earlier position whose intervening characters spell a valid Roman token.
S = "IIIVIIIVIIIVIII"; toks = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII"]
ways = [1] + [0]*len(S)
for i in range(1, len(S) + 1):
for t in toks:
if i >= len(t) and S[i-len(t):i] == t: ways[i] += ways[i-len(t)]
print(ways[-1]) # 4000