Open Source · 7 Languages · 900+ Problems

Project Euler Solutions

Complete solutions in C++, Python & Java — with step-by-step mathematical explanations

All Problems

Problem 497: Drunken Tower of Hanoi

View on Project Euler

Project Euler Problem 497 Solution

EulerSolve provides an optimized solution for Project Euler Problem 497, Drunken Tower of Hanoi, with C++, Python, Java, and a step-by-step mathematical explanation.

Problem Summary For each \(n\), three rods are placed at positions \(3^n\), \(6^n\), and \(9^n\) on a circular track of length \(10^n\). The task is to perform the canonical three-rod Hanoi transfer from the first rod to the third rod, using the middle rod as auxiliary, and to measure the total weighted travel cost of the mover. The mover begins at the middle rod. A direct simulation would expand a Hanoi move list of exponential length, so the solution does not enumerate individual disk states. Instead, it counts how many times each directed rod-to-rod transition occurs and combines those counts with a closed-form cost for the corresponding geometric movement. The required output is $\sum_{n=1}^{10000} E_n \pmod{10^9},$ where \(E_n\) denotes the cost of the \(n\)-disk instance. Mathematical Approach The key observation is that the Hanoi recursion only needs a tiny fixed state: the orientation of the subproblem and the number of directed transitions between the three rods. Step 1: Encode each subproblem by its orientation Label the rods \(0,1,2\) in increasing position order. An orientation \((f,t,a)\) means: move the whole tower from source rod \(f\) to target rod \(t\), using rod \(a\) as auxiliary. Since \((f,t,a)\) is a permutation of \((0,1,2)\), there are exactly six orientations....

Detailed mathematical approach

Problem Summary

For each \(n\), three rods are placed at positions \(3^n\), \(6^n\), and \(9^n\) on a circular track of length \(10^n\). The task is to perform the canonical three-rod Hanoi transfer from the first rod to the third rod, using the middle rod as auxiliary, and to measure the total weighted travel cost of the mover.

The mover begins at the middle rod. A direct simulation would expand a Hanoi move list of exponential length, so the solution does not enumerate individual disk states. Instead, it counts how many times each directed rod-to-rod transition occurs and combines those counts with a closed-form cost for the corresponding geometric movement.

The required output is

$\sum_{n=1}^{10000} E_n \pmod{10^9},$

where \(E_n\) denotes the cost of the \(n\)-disk instance.

Mathematical Approach

The key observation is that the Hanoi recursion only needs a tiny fixed state: the orientation of the subproblem and the number of directed transitions between the three rods.

Step 1: Encode each subproblem by its orientation

Label the rods \(0,1,2\) in increasing position order. An orientation \((f,t,a)\) means: move the whole tower from source rod \(f\) to target rod \(t\), using rod \(a\) as auxiliary. Since \((f,t,a)\) is a permutation of \((0,1,2)\), there are exactly six orientations.

For each orientation and disk count \(n\), define a \(3\times 3\) matrix

$T_n^{(f,t,a)}=\bigl(T_n^{(f,t,a)}(i,j)\bigr)_{0\le i,j\le 2},$

where \(T_n^{(f,t,a)}(i,j)\) is the number of directed transitions \(i\to j\) that occur after the mover has already reached the source rod of that subproblem. This convention leaves the very first walk of the whole instance to a separate term.

Step 2: Derive the transition-count recurrence

Let \(U_{u,v}\) be the \(3\times 3\) matrix whose only nonzero entry is a \(1\) at row \(u\), column \(v\). For one disk, once the mover is already standing at the source rod, the task is just a single loaded move:

$T_1^{(f,t,a)}=U_{f,t}.$

For \(n\ge 2\), the standard Hanoi decomposition says:

1. move the top \(n-1\) disks from \(f\) to \(a\) using \(t\),

2. return from \(a\) to \(f\),

3. carry the largest disk from \(f\) to \(t\),

4. walk from \(t\) to \(a\),

5. move the \(n-1\) disks from \(a\) to \(t\) using \(f\).

Therefore

$T_n^{(f,t,a)}=T_{n-1}^{(f,a,t)}+\Delta^{(f,t,a)}+T_{n-1}^{(a,t,f)},$

with

$\Delta^{(f,t,a)}=U_{a,f}+U_{f,t}+U_{t,a}.$

This recurrence is exact, and it only updates six fixed-size matrices for each new \(n\).

Step 3: Derive the directed cost kernel on the circle

Now fix a circle size \(K\) and rod positions \(1\le x,y\le K\). The code uses a weighted travel rule that depends on direction.

If \(x<y\), the move goes forward through the arc from \(x\) to \(y\). The crossed segment weights are

$2x-1,\ 2x+1,\ \dots,\ 2y-3,$

so the cost is the arithmetic-series sum

$h_K(x,y)=\sum_{r=x}^{y-1}(2r-1)=(y-x)(x+y-2).$

If \(x>y\), the directed move wraps around the far side of the circle. The segment weights are then

$2K-2y+1,\ 2K-2y-1,\ \dots,\ 2K-2x+3,$

which gives

$h_K(x,y)=\sum_{r=y}^{x-1}(2K-2r-1)=(x-y)(2K-x-y).$

Combining both cases,

$h_K(x,y)=\begin{cases} (y-x)(x+y-2), & x<y,\\ (x-y)(2K-x-y), & x>y,\\ 0, & x=y. \end{cases}$

Step 4: Turn transition counts into the cost of one instance

Suppose the three rod positions are \(p_0<p_1<p_2\) on a circle of size \(K\), and the tower must move from rod \(0\) to rod \(2\) using rod \(1\). The mover starts at rod \(1\), so the initial walk is \(1\to 0\), with cost \(h_K(p_1,p_0)\).

After that initial placement, every directed transition counted by \(T_n^{(0,2,1)}(i,j)\) contributes the cost \(h_K(p_i,p_j)\). Hence

$E(n,K,p_0,p_1,p_2)=h_K(p_1,p_0)+\sum_{i=0}^{2}\sum_{j=0}^{2}T_n^{(0,2,1)}(i,j)\,h_K(p_i,p_j).$

This formula converts the abstract transition matrix into the exact weighted cost of the whole \(n\)-disk task.

Step 5: Specialize to Problem 497

For the problem sequence, the geometric parameters are

$K_n=10^n,\qquad p_0=3^n,\qquad p_1=6^n,\qquad p_2=9^n.$

Because

$3^n<6^n<9^n<10^n\qquad (n\ge 1),$

the relative rod order never changes, so the correct branch of \(h_K\) is determined once and for all by the rod indices. The total requested sum is therefore

$S(N)=\sum_{n=1}^{N} E(n,10^n,3^n,6^n,9^n)\pmod{10^9}.$

Since only the last nine digits are needed, every multiplication and addition may be reduced modulo \(10^9\) during the dynamic program.

Step 6: Worked Example \((n,K,p_0,p_1,p_2)=(2,5,1,3,5)\)

For \(n=2\), the canonical orientation is \((0,2,1)\). The recurrence gives

$T_2^{(0,2,1)}=U_{0,1}+U_{1,0}+U_{0,2}+U_{2,1}+U_{1,2}.$

So after the initial walk \(1\to 0\), the mover performs the directed transitions

$0\to 1,\qquad 1\to 0,\qquad 0\to 2,\qquad 2\to 1,\qquad 1\to 2.$

With \(K=5\) and positions \((1,3,5)\), the individual costs are

$h_5(3,1)=12,\qquad h_5(1,3)=4,\qquad h_5(1,5)=16,\qquad h_5(5,3)=4,\qquad h_5(3,5)=12.$

Therefore

$E(2,5,1,3,5)=12+4+12+16+4+12=60,$

which matches the small exact checkpoint used by the implementation.

How the Code Works

The C++, Python, and Java implementations first enumerate the six orientations and store one \(3\times 3\) transition-count matrix for each of them. At \(n=1\), every orientation contains exactly one source-to-target move. For each larger \(n\), every new matrix is produced from two previously stored matrices plus the three fixed bridge transitions \(a\to f\), \(f\to t\), and \(t\to a\).

In parallel, the implementations advance the four power sequences \(3^n\), \(6^n\), \(9^n\), and \(10^n\) modulo \(10^9\). After each update they evaluate the canonical orientation \((0,2,1)\), apply the cost kernel to the current positions, and add the result to a running sum modulo \(10^9\).

The C++ implementation also checks the derivation on two exact small instances before computing the long sum:

$E(2,5,1,3,5)=60,\qquad E(3,20,4,9,17)=2358.$

Those checkpoints confirm that both the transition recurrence and the geometric cost formula are wired correctly.

Complexity Analysis

There are always 6 orientations, and each orientation stores only 9 transition counts. Every step from \(n\) to \(n+1\) performs constant-time arithmetic on this fixed state, followed by one fixed-size cost evaluation. Hence the total running time is \(O(N)\) for summing up to \(N\), and the working memory is \(O(1)\).

Footnotes and References

  1. Problem page: https://projecteuler.net/problem=497
  2. Tower of Hanoi: Wikipedia — Tower of Hanoi
  3. Dynamic programming: Wikipedia — Dynamic programming
  4. Modular arithmetic: Wikipedia — Modular arithmetic

Mathematical approach · C++ solution · Python solution · Java solution

Previous: Problem 496 · All Project Euler solutions · Next: Problem 498

Need help with a problem? Ask me! 💡
e
✦ Euler GLM 5.2
Hi! I'm Euler. Ask me anything about Project Euler problems, math concepts, or solution approaches! 🧮