Open Source · 7 Languages · 900+ Problems

Project Euler Solutions

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

All Problems

Problem 197: Investigating the Behaviour of a Recursively Defined Sequence

View on Project Euler

Project Euler Problem 197 Solution

EulerSolve provides an optimized solution for Project Euler Problem 197, Investigating the Behaviour of a Recursively Defined Sequence, with C++, Python, Java, and a step-by-step mathematical explanation.

Problem Summary The sequence is defined by $u_{0}=-1,\qquad u_{n+1}=f(u_n),\qquad f(x)=\lfloor 2^{30.403243784-x^2}\rfloor\cdot10^{-9}.$ We are asked for \(u_n+u_{n+1}\) when \(n\) is very large. The important point is that this is not a symbolic closed-form problem; it is a discrete dynamical-system problem with a heavily quantized update rule. Mathematical Approach The entire solution comes from understanding what the floor and the factor \(10^{-9}\) do to the orbit. They turn a nonlinear recurrence into a bounded map on a finite grid, and for the given initial value that orbit rapidly falls onto an attracting 2-cycle. A bounded nonlinear map on a decimal lattice Because \(x^2\ge 0\), the exponent \(30.403243784-x^2\) is never larger than \(30.403243784\). Therefore $0\le f(x)\le \lfloor 2^{30.403243784}\rfloor\cdot10^{-9}=1.420000000.$ So after the first iteration, every term of the sequence lies in the compact interval \([0,1.42]\). Even more importantly, the floor forces every value onto the grid $\{k\cdot10^{-9}:0\le k\le 1{,}420{,}000{,}000\}.$ That means the recurrence is not wandering through a continuum of real numbers. It is moving through a finite set of decimal values spaced exactly \(10^{-9}\) apart. Finite state space implies eventual periodicity Once a deterministic map sends a finite set into itself, every orbit must eventually repeat....

Detailed mathematical approach

Problem Summary

The sequence is defined by

$u_{0}=-1,\qquad u_{n+1}=f(u_n),\qquad f(x)=\lfloor 2^{30.403243784-x^2}\rfloor\cdot10^{-9}.$

We are asked for \(u_n+u_{n+1}\) when \(n\) is very large. The important point is that this is not a symbolic closed-form problem; it is a discrete dynamical-system problem with a heavily quantized update rule.

Mathematical Approach

The entire solution comes from understanding what the floor and the factor \(10^{-9}\) do to the orbit. They turn a nonlinear recurrence into a bounded map on a finite grid, and for the given initial value that orbit rapidly falls onto an attracting 2-cycle.

A bounded nonlinear map on a decimal lattice

Because \(x^2\ge 0\), the exponent \(30.403243784-x^2\) is never larger than \(30.403243784\). Therefore

$0\le f(x)\le \lfloor 2^{30.403243784}\rfloor\cdot10^{-9}=1.420000000.$

So after the first iteration, every term of the sequence lies in the compact interval \([0,1.42]\).

Even more importantly, the floor forces every value onto the grid

$\{k\cdot10^{-9}:0\le k\le 1{,}420{,}000{,}000\}.$

That means the recurrence is not wandering through a continuum of real numbers. It is moving through a finite set of decimal values spaced exactly \(10^{-9}\) apart.

Finite state space implies eventual periodicity

Once a deterministic map sends a finite set into itself, every orbit must eventually repeat. In other words, for some indices \(m<n\) we must have \(u_m=u_n\), and from that point onward the sequence becomes periodic.

For this problem, the solutions do not try to classify every possible eventual cycle of \(f\). They only need the orbit starting from \(u_0=-1\). Numerically, that orbit very quickly approaches a cycle of length 2.

It is useful to introduce the two-step map

$g(x)=f(f(x)).$

If the late orbit alternates between two values \(a\) and \(b\), then

$a=f(b),\qquad b=f(a),\qquad g(a)=a,\qquad g(b)=b.$

So the two-cycle of \(f\) appears as fixed points of the even-step recurrence \(u_{n+2}=g(u_n)\).

Worked orbit from the given initial value

Starting from \(u_0=-1\), the first few terms are

$u_1=0.710000000,\qquad u_2=1.001242148,\qquad u_3=0.708777686,\qquad u_4=1.002446415.$

Continuing a little farther gives

$u_5=0.707593212,\qquad u_6=1.003612800,\qquad u_7=0.706446531,\qquad u_8=1.004741400.$

This already shows the pattern that the implementations exploit: the odd subsequence moves downward, the even subsequence moves upward, and the orbit is being squeezed toward an alternating pair rather than toward a single fixed point.

After a modest burn-in, the late terms are

$u_{1000}=1.029461839,\qquad u_{1001}=0.681175878,\qquad u_{1002}=1.029461839.$

So to the required output precision the recurrence has settled on the 2-cycle

$1.029461839\longleftrightarrow 0.681175878.$

Why the required quantity is the two-cycle sum

If \(u_n\) alternates between \(a\) and \(b\) for large \(n\), then the parity of \(n\) only swaps the order of the pair. In either case,

$u_n+u_{n+1}=a+b.$

For the present orbit, the stabilized value is therefore

$1.029461839+0.681175878=1.710637717.$

This is why the implementations do not need to detect the cycle explicitly. A sufficiently late consecutive pair already contains the final answer.

How the Code Works

Evaluate the map exactly as stated

The C++, Python, and Java implementations all use the same update rule: square the current value, subtract from \(30.403243784\), raise 2 to that power, take the floor, and multiply by \(10^{-9}\). No algebraic simplification is attempted, because the floor is the crucial feature of the problem.

Burn in the orbit

The implementations start from \(u=-1\) and repeatedly apply the map. The Python and Java versions use 1000 iterations, while the C++ version defaults to 100000 and allows that count to be adjusted. All of those choices are comfortably large compared with the very fast observed approach to the 2-cycle.

Use one extra iterate to read the answer

After the burn-in phase, the implementation computes one more value \(v=f(u)\) and returns \(u+v\). That sum is exactly what the mathematics above predicts: once \(u\) is a late term on the attracting 2-cycle, \(u\) and \(v\) are the two alternating states whose sum is independent of parity.

The C++ version also includes sanity checks. One verifies the first nontrivial value \(f(-1)=0.710000000\); another verifies that a long run gives the stabilized sum \(1.710637717\). These checks match the underlying dynamical picture.

Complexity Analysis

If the recurrence is iterated \(N\) times, the running time is \(O(N)\). Each step performs one exponentiation, one floor operation, and a small amount of arithmetic.

The memory usage is \(O(1)\), because the implementation only keeps the current value and then one additional iterate for the final sum. No history table, cycle-detection structure, or memoization is required.

Footnotes and References

  1. Project Euler Problem 197: https://projecteuler.net/problem=197
  2. Iterated function: Wikipedia - Iterated function
  3. Recurrence relation: Wikipedia - Recurrence relation
  4. Fixed point: Wikipedia - Fixed point
  5. Periodic point: Wikipedia - Periodic point
  6. Floor and ceiling functions: Wikipedia - Floor and ceiling functions

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

Previous: Problem 196 · All Project Euler solutions · Next: Problem 198

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