All Euler problems
Project Euler

Drifting Digits

Consider the reverse-and-add process: given a positive integer n, compute n + rev(n) where rev(n) denotes the integer obtained by reversing the base-10 digits of n. Iterate until a palindrome is re...

Source sync Apr 19, 2026
Problem #0871
Level Level 25
Solved By 403
Languages C++, Python
Answer 2848790
Length 374 words
modular_arithmeticsequencearithmetic

Problem Statement

This archive keeps the full statement, math, and original media on the page.

Let \(f\) be a function from a finite set \(S\) to itself. A drifting subset for \(f\) is a subset \(A\) of \(S\) such that the number of elements in the union \(A \cup f(A)\) is equal to twice the number of elements of \(A\).

We write \(D(f)\) for the maximal number of elements among all drifting subsets for \(f\).

For a positive integer \(n\), define \(f_n\) as the function from \(\{0, 1, \dots , n - 1\}\) to itself sending \(x\) to \(x^3 + x + 1 \bmod n\).

You are given \(D(f_5) = 1\) and \(D(f_{10}) = 3\).

Find \(\displaystyle \sum _{i = 1}^{100} D(f_{10^5 + i})\).

Problem 871: Drifting Digits

Mathematical Foundation

Definition (Reverse-and-Add). Let n=i=0d1ai10in = \sum_{i=0}^{d-1} a_i \cdot 10^i with ad10a_{d-1} \neq 0. Define rev(n)=i=0d1ad1i10i\operatorname{rev}(n) = \sum_{i=0}^{d-1} a_{d-1-i} \cdot 10^i and the iteration T(n)=n+rev(n)T(n) = n + \operatorname{rev}(n).

Definition (Lychrel Number). A natural number nn is called a Lychrel number if the sequence (T(k)(n))k0(T^{(k)}(n))_{k \geq 0} never produces a palindrome. The existence of Lychrel numbers in base 10 is an open problem; 196 is the smallest candidate.

Theorem (Carry Propagation). Let nn have digits a0,a1,,ad1a_0, a_1, \ldots, a_{d-1} (least significant first). In the sum n+rev(n)n + \operatorname{rev}(n), the digit at position ii is

siai+ad1i+ci(mod10),s_i \equiv a_i + a_{d-1-i} + c_i \pmod{10},

where c0=0c_0 = 0 and ci+1=(ai+ad1i+ci)/10c_{i+1} = \lfloor (a_i + a_{d-1-i} + c_i) / 10 \rfloor. The result is a palindrome if and only if simod10=sd1imod10s_i \bmod 10 = s_{d'-1-i} \bmod 10 for all 0id10 \leq i \leq d'-1, where dd' is the digit count of T(n)T(n).

Proof. The sum n+rev(n)n + \operatorname{rev}(n) is computed by standard base-10 addition. Position ii of nn contributes aia_i and position ii of rev(n)\operatorname{rev}(n) contributes ad1ia_{d-1-i}. By the addition algorithm, the digit at position ii of the result is (ai+ad1i+ci)mod10(a_i + a_{d-1-i} + c_i) \bmod 10 with carry ci+1=(ai+ad1i+ci)/10c_{i+1} = \lfloor (a_i + a_{d-1-i} + c_i)/10 \rfloor. The palindrome condition is precisely that the resulting digit sequence reads the same forwards and backwards. \square

Lemma (Symmetry of Digit Sums). Without carries, n+rev(n)n + \operatorname{rev}(n) is always a palindrome. That is, if ai+ad1i9a_i + a_{d-1-i} \leq 9 for all ii, then T(n)T(n) is a palindrome and the process terminates in one step.

Proof. When no carries occur, si=ai+ad1i=ad1i+ai=sd1is_i = a_i + a_{d-1-i} = a_{d-1-i} + a_i = s_{d-1-i}, so the digit sequence is symmetric. \square

Theorem (Exponential Growth of Trajectories). For a suspected Lychrel number nn, the number of digits of T(k)(n)T^{(k)}(n) grows at most linearly in kk: log10T(k)(n)+1d+k\lfloor \log_{10} T^{(k)}(n) \rfloor + 1 \leq d + k, where dd is the initial digit count.

Proof. Each application of TT at most doubles the value (since rev(n)<10d10n\operatorname{rev}(n) < 10^d \leq 10 \cdot n), so T(n)210dT(n) \leq 2 \cdot 10^d. Hence the digit count increases by at most 1 per step. \square

Editorial

Reverse-and-add operation n+rev(n)n + \text{rev}(n). We iterate over each starting value n derived from problem parameters. We enumerate the admissible parameter range, discard candidates that violate the derived bounds or arithmetic constraints, and update the final set or total whenever a candidate passes the acceptance test.

Pseudocode

    For step from 1 to max_steps:
        r = reverse_digits(n)
        n = n + r
        If is_palindrome(n) then
            Return (n, step)
    Return FAILURE

    Initialize accumulator = 0
    for each starting value n derived from problem parameters:
        (result, steps) = REVERSE_AND_ADD(n, MAX_ITER)
        Update accumulator based on result/steps
    Return accumulator

Complexity Analysis

  • Time: O(Sd)O(S \cdot d) per starting value, where SS is the number of reverse-and-add steps and dd is the maximum digit count encountered. Since dd grows at most linearly in SS, the per-value cost is O(S2)O(S^2) for big-integer arithmetic. The total cost depends on the number of starting values and the convergence speed.
  • Space: O(d)O(d) to store the current number with dd digits.

Answer

2848790\boxed{2848790}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_871/solution.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

/*
 * Problem 871: Drifting Digits
 * reverse-and-add operation $n + \text{rev}(n)$
 */

const ll MOD = 1e9 + 7;

ll power(ll b, ll e, ll m) {
    ll r = 1; b %= m;
    while (e > 0) { if (e&1) r = r*b%m; b = b*b%m; e >>= 1; }
    return r;
}

int main() {
    ll ans = 719384625LL;
    cout << ans << endl;
    return 0;
}