Open Source · 7 Languages · 900+ Problems

Project Euler Solutions

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

All Problems

Problem 728: Circle of Coins

View on Project Euler

Project Euler Problem 728 Solution

EulerSolve provides an optimized solution for Project Euler Problem 728, Circle of Coins, with C++, Python, Java, and a step-by-step mathematical explanation.

Problem Summary For each pair \((n,k)\) with \(1 \le k \le n\), the circle-of-coins problem has a counting function \(F(n,k)\) for the admissible binary coin configurations associated with that pair. The overall task is to evaluate $S(N)=\sum_{n=1}^{N}\sum_{k=1}^{n} F(n,k)\pmod{10^9+7}.$ The key point in the implementations is that the combinatorics collapse to arithmetic data: only \(\gcd(n,k)\), the exponent of \(2\) dividing \(n\) and \(k\), and a totient-based regrouping are needed. That removes any need to enumerate coin states directly. Mathematical Approach The C++, Python, and Java implementations all use the same arithmetic decomposition. Once the fixed-pair formula is known, the remaining work is to reorganize the double sum so that equal contributions are collected together efficiently. Step 1: Closed Form for a Fixed Pair Let $g=\gcd(n,k),$ and let \(v_2(x)\) denote the exponent of \(2\) in \(x\). The implementations use the closed form $F(n,k)=\begin{cases} 2^{n-g+1}, & v_2(k)\le v_2(n),\\ 2^{n-g}, & v_2(k)>v_2(n). \end{cases}$ So the entire dependence on the original circle is compressed into two quantities: the common divisor \(g\), which controls the main exponent \(n-g\), and a single parity-sensitive comparison of 2-adic valuations, which decides whether there is one extra factor of \(2\)....

Detailed mathematical approach

Problem Summary

For each pair \((n,k)\) with \(1 \le k \le n\), the circle-of-coins problem has a counting function \(F(n,k)\) for the admissible binary coin configurations associated with that pair. The overall task is to evaluate

$S(N)=\sum_{n=1}^{N}\sum_{k=1}^{n} F(n,k)\pmod{10^9+7}.$

The key point in the implementations is that the combinatorics collapse to arithmetic data: only \(\gcd(n,k)\), the exponent of \(2\) dividing \(n\) and \(k\), and a totient-based regrouping are needed. That removes any need to enumerate coin states directly.

Mathematical Approach

The C++, Python, and Java implementations all use the same arithmetic decomposition. Once the fixed-pair formula is known, the remaining work is to reorganize the double sum so that equal contributions are collected together efficiently.

Step 1: Closed Form for a Fixed Pair

Let

$g=\gcd(n,k),$

and let \(v_2(x)\) denote the exponent of \(2\) in \(x\). The implementations use the closed form

$F(n,k)=\begin{cases} 2^{n-g+1}, & v_2(k)\le v_2(n),\\ 2^{n-g}, & v_2(k)>v_2(n). \end{cases}$

So the entire dependence on the original circle is compressed into two quantities: the common divisor \(g\), which controls the main exponent \(n-g\), and a single parity-sensitive comparison of 2-adic valuations, which decides whether there is one extra factor of \(2\).

Step 2: Separate the GCD from the Reduced Step

Write

$n=t h,\qquad k=t r,\qquad t=\gcd(n,k),\qquad \gcd(r,h)=1.$

Then \(t\) is exactly the gcd that appears in the fixed-pair formula, so

$n-g=t h-t=t(h-1).$

After removing the common factor \(t\), every pair \((n,k)\) is described by a reduced denominator \(h\) and a reduced residue \(r\) coprime to \(h\). The formula becomes

$F(t h,t r)=\begin{cases} 2^{t(h-1)+1}, & v_2(r)\le v_2(h),\\ 2^{t(h-1)}, & v_2(r)>v_2(h). \end{cases}$

This shows that, for fixed \(h\) and \(t\), all dependence on the reduced step is packed into how many coprime residues \(r\) satisfy the valuation test.

Step 3: Count the Reduced Residues for Fixed \(h\)

Now fix \(h \ge 2\) and sum over all \(r\) with \(1 \le r \le h\) and \(\gcd(r,h)=1\).

If \(h\) is even, every residue coprime to \(h\) must be odd. Hence \(v_2(r)=0\le v_2(h)\), so every reduced residue contributes the larger value \(2^{t(h-1)+1}\). Since there are \(\varphi(h)\) such residues, their total contribution is

$\varphi(h)\cdot 2^{t(h-1)+1}=2\varphi(h)\,2^{t(h-1)}.$

If \(h\) is odd, the reduced residues split evenly into odd and even values. Indeed, for every reduced residue \(r\), the paired residue \(h-r\) is also reduced and has opposite parity. Therefore exactly half of the \(\varphi(h)\) residues satisfy \(v_2(r)=0=v_2(h)\), while the other half fail the inequality.

Step 4: Derive the Coefficient \(c(h)\)

From the parity split above, the total contribution for one fixed \(h \ge 2\) and one fixed \(t\) is

$c(h)\,2^{t(h-1)},$

where

$c(h)=\begin{cases} 2\varphi(h), & h \text{ even},\\ \dfrac{3\varphi(h)}{2}, & h \text{ odd}. \end{cases}$

The odd case is just

$\frac{\varphi(h)}{2}\cdot 2^{t(h-1)+1}+\frac{\varphi(h)}{2}\cdot 2^{t(h-1)} =\frac{3\varphi(h)}{2}\,2^{t(h-1)}.$

This is the crucial compression step: once pairs are grouped by \(h\), all the messy dependence on \(k\) is replaced by a single totient-based coefficient.

Step 5: Rebuild the Whole Sum

The case \(h=1\) is special. Then \(k=n\), so \(g=n\) and the fixed-pair formula gives \(F(n,n)=2\). Summed over \(n=1,\dots,N\), this contributes

$2N.$

For every \(h \ge 2\), the remaining parameter is \(t\), and the condition \(n=t h \le N\) means

$1\le t\le \left\lfloor\frac{N}{h}\right\rfloor.$

Therefore the full sum becomes

$\boxed{S(N)=2N+\sum_{h=2}^{N} c(h)\sum_{t=1}^{\lfloor N/h\rfloor} 2^{t(h-1)} \pmod{10^9+7}.}$

Mathematically the inner sum is a finite geometric progression, but the implementations simply step through its exponents directly after precomputing powers of \(2\).

Worked Example: \(N=3\)

The special term is

$2N=6.$

For \(h=2\), we have \(\varphi(2)=1\) and \(c(2)=2\). Also \(\lfloor 3/2\rfloor=1\), so this block contributes

$2\cdot 2^{1}=4.$

For \(h=3\), we have \(\varphi(3)=2\) and \(c(3)=3\). Also \(\lfloor 3/3\rfloor=1\), so this block contributes

$3\cdot 2^{2}=12.$

Hence

$S(3)=6+4+12=22,$

which matches the checkpoint used by the implementation. A single-pair checkpoint is \(F(9,3)=2^{9-3+1}=128\), because \(\gcd(9,3)=3\) and \(v_2(3)\le v_2(9)\).

How the Code Works

The implementations first build Euler's totient values for all integers up to \(N\) with a linear sieve. They also precompute the table

$2^0,2^1,\dots,2^N \pmod{10^9+7},$

so every power lookup in the main sum is constant time.

After that, the algorithm starts with the special contribution \(2N\). It then iterates through \(h=2,3,\dots,N\), computes the coefficient \(c(h)\) from the parity of \(h\) and the totient value, and adds

$c(h)\,2^{t(h-1)}$

for each \(t=1,\dots,\lfloor N/h\rfloor\). All arithmetic is reduced modulo \(10^9+7\) after each addition. The C++, Python, and Java implementations follow exactly the same mathematical plan; the C++ version also includes small checkpoint assertions before producing the final large-input result.

Complexity Analysis

The totient sieve runs in \(O(N)\) time and uses \(O(N)\) memory. The double summation over blocks costs

$\sum_{h=2}^{N}\left\lfloor\frac{N}{h}\right\rfloor=O(N\log N).$

Therefore the total running time is \(O(N\log N)\), while the memory usage remains \(O(N)\).

Footnotes and References

  1. Problem page: Project Euler 728 — Circle of Coins
  2. Greatest common divisor: Wikipedia — Greatest common divisor
  3. Euler's totient function: Wikipedia — Euler's totient function
  4. \(p\)-adic valuation, including the special case \(v_2\): Wikipedia — \(p\)-adic valuation
  5. Geometric progression: Wikipedia — Geometric progression

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

Previous: Problem 727 · All Project Euler solutions · Next: Problem 729

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