Open Source · 7 Languages · 900+ Problems

Project Euler Solutions

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

All Problems

Problem 235: An Arithmetic Geometric Sequence

View on Project Euler

Project Euler Problem 235 Solution

EulerSolve provides an optimized solution for Project Euler Problem 235, An Arithmetic Geometric Sequence, with C++, Python, Java, and a step-by-step mathematical explanation.

Problem Summary Problem 235 asks for the real number \(r > 1\) for which the arithmetic-geometric sequence $u_k=(900-3k)r^{k-1}$ has partial sum $s_n(r)=\sum_{k=1}^{n}u_k,\qquad s_{5000}(r)=-600000000000.$ The coefficient \(900-3k\) is positive for \(k\le 299\), zero at \(k=300\), and negative afterwards. The problem is therefore a balancing act: choose \(r\) so that the late negative terms, which are amplified by the geometric factor \(r^{k-1}\), pull the total down to exactly \(-6\times 10^{11}\). The required output is \(r\) rounded to 12 decimal places. Mathematical Approach This is a one-variable root-finding problem, but the finite sum has enough structure that we can see why the solution lies only slightly above 1 and why a simple bracketing method is numerically reliable....

Detailed mathematical approach

Problem Summary

Problem 235 asks for the real number \(r > 1\) for which the arithmetic-geometric sequence

$u_k=(900-3k)r^{k-1}$

has partial sum

$s_n(r)=\sum_{k=1}^{n}u_k,\qquad s_{5000}(r)=-600000000000.$

The coefficient \(900-3k\) is positive for \(k\le 299\), zero at \(k=300\), and negative afterwards. The problem is therefore a balancing act: choose \(r\) so that the late negative terms, which are amplified by the geometric factor \(r^{k-1}\), pull the total down to exactly \(-6\times 10^{11}\). The required output is \(r\) rounded to 12 decimal places.

Mathematical Approach

This is a one-variable root-finding problem, but the finite sum has enough structure that we can see why the solution lies only slightly above 1 and why a simple bracketing method is numerically reliable.

Collapsing the finite arithmetic-geometric sum

Separate the sum into a pure geometric part and a weighted geometric part:

$s_n(r)=900\sum_{k=1}^{n}r^{k-1}-3\sum_{k=1}^{n}kr^{k-1}.$

For \(r\neq 1\), the standard finite-sum identities are

$\sum_{k=1}^{n}r^{k-1}=\frac{1-r^n}{1-r},\qquad \sum_{k=1}^{n}kr^{k-1}=\frac{1-(n+1)r^n+nr^{n+1}}{(1-r)^2}.$

Substituting them gives the closed form

$s_n(r)=\frac{897-900r+(3n-897)r^n+(900-3n)r^{n+1}}{(1-r)^2}.$

For the actual problem this becomes

$s_{5000}(r)=\frac{897-900r+14103r^{5000}-14100r^{5001}}{(1-r)^2}.$

This formula exposes the main geometry of the problem: when \(r\) is only a little larger than 1, the two huge tail terms \(14103r^{5000}\) and \(14100r^{5001}\) nearly cancel, and the desired root appears precisely in that narrow transition zone.

Why \(r=1\) is the natural anchor point

The rational form has a removable singularity at \(r=1\), but the original definition is just a finite polynomial sum, so the function itself is perfectly regular there. Evaluating the series directly at \(r=1\) gives a concrete worked example:

$s_{5000}(1)=\sum_{k=1}^{5000}(900-3k)=900\cdot 5000-3\cdot\frac{5000\cdot 5001}{2}=-33{,}007{,}500.$

This is far above the target \(-6\times 10^{11}\), so the solution must satisfy \(r>1\). This exact identity is also a useful checkpoint because it confirms that the summation logic is aligned with the mathematics before any floating-point search begins.

Why the interval \([1,1.2]\) contains the answer

At the right endpoint, the high-power tail is overwhelmingly negative. In the closed form, the dominant contribution is

$14103r^{5000}-14100r^{5001}=14100r^{5000}\left(\frac{14103}{14100}-r\right).$

Once \(r\) is appreciably larger than \(14103/14100\approx 1.000212766\), this contribution is negative, and at \(r=1.2\) its magnitude is enormous. That pushes the whole sum well below \(-6\times 10^{11}\). Because \(s_{5000}(r)\) is continuous, there is at least one root inside \([1,1.2]\).

The implementations use the additional problem-specific fact that within this bracket the sum decreases through the target only once, so the interval can be shrunk safely by bisection.

Why bisection is enough

Even after the closed-form reduction, the equation \(s_{5000}(r)=-600000000000\) is still a degree-4999 problem in \(r\). There is no practical symbolic shortcut for the exact root, and derivative-based methods are unnecessary because the search interval is already known. For a continuous function with a single crossing, bisection is the simplest robust choice.

How the Code Works

The C++, Python, and Java implementations all avoid using the rational closed form during evaluation. Instead they build the series in one pass, starting with the current power equal to 1 and multiplying by \(r\) after every term. If \(P_k=r^{k-1}\), the updates are

$P_1=1,\qquad P_{k+1}=rP_k,\qquad S_k=S_{k-1}+(900-3k)P_k.$

After \(k\) iterations, the invariant is exact: \(S_k=s_k(r)\) and the stored power for the next step is \(r^k\). This matches the mathematical definition term for term and avoids the cancellation that can occur if one substitutes into the \((1-r)^2\) formula very close to \(r=1\).

One pass for the sum

Each evaluation of \(s_{5000}(r)\) touches the 5000 terms once, so the numerical core is only repeated multiplication and addition. There is no table of powers and no recursion depth to manage; the sum is streamed from left to right.

The bracketing loop

The solver starts with a lower endpoint at 1 and an upper endpoint at 1.2. At each iteration it evaluates the midpoint. If the midpoint sum is still above the target, the root must be further right, so the lower endpoint moves up; otherwise the upper endpoint moves down. The key invariant is that the left endpoint always remains on the "sum too large" side while the right endpoint remains on the "sum too small" side.

After 200 halving steps, the interval width is vastly smaller than \(10^{-12}\), so formatting the midpoint to 12 decimal places is safe. The core numerical loop is the same in all three languages; one version additionally exposes the problem parameters as optional inputs and verifies the exact \(r=1\) checkpoint before solving.

Complexity Analysis

One evaluation of the series costs \(O(n)\) time and \(O(1)\) memory. With \(n=5000\) and a fixed 200 bisection steps, the full computation performs about \(5000\times 200=1{,}000{,}000\) term updates, so the practical runtime is very small.

In asymptotic form, if the number of bisection iterations is \(I\), the total cost is \(O(nI)\) time and \(O(1)\) space. Because \(I\) is fixed here, the implementation is effectively linear in \(n\).

Footnotes and References

  1. Project Euler Problem 235: https://projecteuler.net/problem=235
  2. Arithmetic-geometric sequence: Wikipedia - Arithmetico-geometric sequence
  3. Geometric series: Wikipedia - Geometric series
  4. Bisection method: Wikipedia - Bisection method

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

Previous: Problem 234 · All Project Euler solutions · Next: Problem 236

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