Open Source · 7 Languages · 900+ Problems

Project Euler Solutions

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

All Problems

Problem 837: Amidakuji

View on Project Euler

Project Euler Problem 837 Solution

EulerSolve provides an optimized solution for Project Euler Problem 837, Amidakuji, with C++, Python, Java, and a step-by-step mathematical explanation.

Problem Summary There are three vertical lines and two allowed adjacent swaps. Operation \(A\) swaps the first and second lines, and operation \(B\) swaps the second and third lines. Among all words that contain exactly \(m\) copies of \(A\) and exactly \(n\) copies of \(B\), we must count those whose total permutation is the identity. The required answer is taken modulo \(M=1234567891\). A direct dynamic program over all prefixes and all six permutations is useful only for tiny checks. For the real input sizes, the key is to compress the word into consecutive pairs and count those pairs analytically. Mathematical Approach Step 1: Model the Ladder as Permutations Work in the symmetric group \(S_3\): $A=(12),\qquad B=(23).$ Both generators are transpositions, so they are odd permutations. The identity permutation is even....

Detailed mathematical approach

Problem Summary

There are three vertical lines and two allowed adjacent swaps. Operation \(A\) swaps the first and second lines, and operation \(B\) swaps the second and third lines. Among all words that contain exactly \(m\) copies of \(A\) and exactly \(n\) copies of \(B\), we must count those whose total permutation is the identity.

The required answer is taken modulo \(M=1234567891\). A direct dynamic program over all prefixes and all six permutations is useful only for tiny checks. For the real input sizes, the key is to compress the word into consecutive pairs and count those pairs analytically.

Mathematical Approach

Step 1: Model the Ladder as Permutations

Work in the symmetric group \(S_3\):

$A=(12),\qquad B=(23).$

Both generators are transpositions, so they are odd permutations. The identity permutation is even. Therefore, if \(m+n\) is odd, then no word can evaluate to the identity and

$F(m,n)=0.$

From now on, assume \(m+n\) is even and write

$m+n=2t,\qquad t=\frac{m+n}{2}.$

Step 2: Group the Word into Consecutive Pairs

Split any word of length \(2t\) into \(t\) adjacent blocks:

$\bigl(x_1x_2\bigr)\bigl(x_3x_4\bigr)\cdots\bigl(x_{2t-1}x_{2t}\bigr),\qquad x_i\in\{A,B\}.$

Now set

$e=\text{identity},\qquad r=AB=(123),\qquad r^2=BA=(132).$

Each pair belongs to the cyclic subgroup \(\{e,r,r^2\}\), because

$AA=e,\qquad BB=e,\qquad AB=r,\qquad BA=r^2.$

Suppose exactly \(k\) of the \(t\) pairs are mixed, meaning they are either \(AB\) or \(BA\). Then the remaining pairs must be neutral pairs \(AA\) and \(BB\). Their counts are forced:

$u=\frac{m-k}{2},\qquad v=\frac{n-k}{2}.$

So \(k\) is admissible exactly when

$0\le k\le \min(m,n),\qquad k\equiv m\pmod 2.$

Once \(k\) is fixed, the number of ways to choose which of the \(t\) pair positions are \(AA\), which are \(BB\), and which are mixed is the multinomial coefficient

$T_k=\frac{t!}{u!\,v!\,k!}=\frac{t!}{\left(\frac{m-k}{2}\right)!\left(\frac{n-k}{2}\right)!k!}.$

This counts the block layout, but it does not yet distinguish whether a mixed block is \(AB\) or \(BA\).

Step 3: Count the Mixed Blocks That Multiply to the Identity

Inside the \(k\) mixed positions, let exactly \(j\) blocks be \(AB=r\) and the remaining \(k-j\) blocks be \(BA=r^2\). Their product is

$r^j(r^2)^{k-j}=r^{j+2(k-j)}=r^{2j-k}.$

This equals the identity exactly when

$2j-k\equiv 0\pmod 3.$

Therefore the number of valid orientations of the \(k\) mixed blocks is

$R_k=\sum_{\substack{0\le j\le k\\2j-k\equiv 0\pmod 3}}\binom{k}{j}.$

This sum has a clean closed form. Let \(\omega\neq 1\) be a complex cube root of unity, so \(\omega^3=1\). A roots-of-unity filter gives

$R_k=\frac{1}{3}\sum_{q=0}^{2}\omega^{-2kq}(1+\omega^q)^k.$

Evaluating the three terms yields

$R_k=\frac{2^k+2(-1)^k}{3}.$

Step 4: Combine the Layout Count and the Orientation Count

For each admissible \(k\), the choices of block layout and the choices of mixed-block orientations are independent. Hence

$F(m,n)=\sum_{\substack{0\le k\le \min(m,n)\\k\equiv m\pmod 2}} T_k\,R_k \pmod{M}.$

Substituting the explicit formulas gives

$F(m,n)=\sum_{\substack{0\le k\le \min(m,n)\\k\equiv m\pmod 2}}\frac{t!}{\left(\frac{m-k}{2}\right)!\left(\frac{n-k}{2}\right)!k!}\cdot\frac{2^k+2(-1)^k}{3}\pmod{M}.$

This is the closed summation used by the implementations.

Step 5: Derive the Recurrence Used by the Implementation

Let \(k_0=m\bmod 2\), the smallest admissible value of \(k\). The initial combinatorial factor is

$T_{k_0}= \begin{cases} \binom{t}{m/2}, & k_0=0,\\ t\binom{t-1}{(m-1)/2}, & k_0=1. \end{cases}$

For later terms, taking the ratio of consecutive admissible values gives

$\frac{T_{k+2}}{T_k}=\frac{(m-k)(n-k)}{4(k+1)(k+2)}.$

So once one term is known, the next one is obtained with constant-time modular arithmetic. Also, when \(k\) increases by \(2\), the factor \(2^k\) is multiplied by \(4\), while \((-1)^k\) stays unchanged because the parity of \(k\) never changes inside the loop.

Worked Example: \(m=n=3\)

Here \(m+n=6\), so \(t=3\), and admissible values of \(k\) are \(1\) and \(3\).

For \(k=1\), we have

$T_1=\frac{3!}{1!\,1!\,1!}=6,\qquad R_1=\frac{2^1+2(-1)^1}{3}=0.$

So all layouts with exactly one mixed pair contribute nothing, because a single nontrivial element of order \(3\) cannot be the identity.

For \(k=3\), we get

$T_3=\frac{3!}{0!\,0!\,3!}=1,\qquad R_3=\frac{2^3+2(-1)^3}{3}=2.$

Thus

$F(3,3)=1\cdot 2=2.$

The two words are the fully alternating ones:

$ABABAB,\qquad BABABA.$

How the Code Works

The C++, Python, and Java implementations all evaluate the same formula modulo \(1234567891\). They first handle the parity test \(m+n\) odd \(\Rightarrow 0\), then set \(t=(m+n)/2\) and start from the smallest admissible \(k\).

The initial factor \(T_{k_0}\) is computed through a binomial coefficient modulo \(M\). Since modular division is needed, the implementation uses modular inverses under the prime modulus, obtained by fast exponentiation. To avoid computing one inverse at a time, it builds inverses for long consecutive ranges in batches and reuses them inside the product.

After that, the program walks through \(k,k+2,k+4,\dots\). At each step it updates the current multinomial factor with the ratio

$\frac{(m-k)(n-k)}{4(k+1)(k+2)}$

updates the power \(2^k\) by multiplying by \(4\), multiplies by the modular inverse of \(3\), and adds the current contribution to the running answer. The whole computation therefore uses the closed form directly and never builds a large \(O(mn)\) dynamic-programming table over the six states of \(S_3\).

Complexity Analysis

The number of admissible values of \(k\) is \(1+\left\lfloor\frac{\min(m,n)-k_0}{2}\right\rfloor\), so the main summation is linear in \(\min(m,n)\). Computing the starting binomial factor is also linear in the smaller half-count, so the total running time is \(O(\min(m,n))\) modular multiplications.

The implementations store only a few scalar values plus a temporary batch of modular inverses. If the batch size is denoted by \(B\), the extra memory is \(O(B)\); with the batch size treated as a fixed engineering constant, the working memory is effectively constant with respect to \(m\) and \(n\).

Footnotes and References

  1. Problem page: Project Euler 837
  2. Symmetric group: Wikipedia — Symmetric group
  3. Roots of unity: Wikipedia — Root of unity
  4. Multinomial theorem: Wikipedia — Multinomial theorem
  5. Fermat's little theorem: Wikipedia — Fermat's little theorem

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

Previous: Problem 836 · All Project Euler solutions · Next: Problem 838

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! 🧮