All Euler problems
Project Euler

Lychrel Numbers

A Lychrel number is a number that never forms a palindrome through the reverse-and-add process. Working with the assumption that a number is Lychrel if it has not produced a palindrome within 50 it...

Source sync Apr 19, 2026
Problem #0055
Level Level 02
Solved By 59,653
Languages C++, Python
Answer 249
Length 520 words
modular_arithmeticbrute_forcearithmetic

Problem Statement

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

If we take $47$, reverse and add, $47 + 74 = 121$, which is palindromic.

Not all numbers produce palindromes so quickly. For example, \begin{align*} 349 + 943 &= 1292\\ 1292 + 2921 &= 4213\\ 4213 + 3124 &= 7337 \end{align*} That is, $349$ took three iterations to arrive at a palindrome.

Although no one has proved it yet, it is thought that some numbers, like $196$, never produce a palindrome. A number that never forms a palindrome through the reverse and add process is called a Lychrel number. Due to the theoretical nature of these numbers, and for the purpose of this problem, we shall assume that a number is Lychrel until proven otherwise. In addition you are given that for every number below ten-thousand, it will either (i) become a palindrome in less than fifty iterations, or, (ii) no one, with all the computing power that exists, has managed so far to map it to a palindrome. In fact, $10677$ is the first number to be shown to require over fifty iterations before producing a palindrome: $4668731596684224866951378664$ ($53$ iterations, $28$-digits).

Surprisingly, there are palindromic numbers that are themselves Lychrel numbers; the first example is $4994$.

How many Lychrel numbers are there below ten-thousand?

s

NOTE: Wording was modified slightly on 24 April 2007 to emphasise the theoretical nature of Lychrel numbers.

Problem 55: Lychrel Numbers

Mathematical Development

Formal Development

Definition 1 (Digit Reversal). For a positive integer nn with decimal representation dkdk1d1d0d_k d_{k-1} \cdots d_1 d_0 (where dk0d_k \neq 0), define the digit reversal

rev(n)=i=0kdi10ki=d0d1dk1dk.\mathrm{rev}(n) = \sum_{i=0}^{k} d_i \cdot 10^{k-i} = d_0 d_1 \cdots d_{k-1} d_k.

Definition 2 (Reverse-and-Add Operator). The reverse-and-add operator is

R(n)=n+rev(n).R(n) = n + \mathrm{rev}(n).

For k1k \geq 1, denote the kk-fold composition R(k)=RRRkR^{(k)} = \underbrace{R \circ R \circ \cdots \circ R}_{k} with R(0)(n)=nR^{(0)}(n) = n.

Definition 3 (Palindrome). An integer nn is a palindrome if n=rev(n)n = \mathrm{rev}(n), equivalently, if di=dkid_i = d_{k-i} for all 0ik0 \leq i \leq k.

Definition 4 (Lychrel Candidate). For a positive integer bound LL, we say nn is a Lychrel candidate with respect to LL if R(k)(n)R^{(k)}(n) is not a palindrome for all 1kL1 \leq k \leq L. In this problem, L=50L = 50.

Theorem 1 (Digit Growth Bound). If nn has dd digits, then R(n)R(n) has at most d+1d + 1 digits.

Proof. Since nn has dd digits, n<10dn < 10^d. The reversal rev(n)\mathrm{rev}(n) also has at most dd digits (it has exactly dd digits if d00d_0 \neq 0, and fewer otherwise, but in all cases rev(n)<10d\mathrm{rev}(n) < 10^d). Therefore

R(n)=n+rev(n)<10d+10d=210d<10d+1,R(n) = n + \mathrm{rev}(n) < 10^d + 10^d = 2 \cdot 10^d < 10^{d+1},

so R(n)R(n) has at most d+1d + 1 digits. \blacksquare

Corollary 1 (Iterated Growth). Starting from nn with d0d_0 digits, the value R(k)(n)R^{(k)}(n) has at most d0+kd_0 + k digits for all k0k \geq 0.

Proof. By induction on kk, applying Theorem 1 at each step. \blacksquare

Theorem 2 (Symmetrization Without Carries). Let n=i=0kdi10in = \sum_{i=0}^{k} d_i \cdot 10^i. Then

R(n)=i=0k(di+dki)10i+(carry corrections).R(n) = \sum_{i=0}^{k} (d_i + d_{k-i}) \cdot 10^i + \text{(carry corrections)}.

In the absence of carries (i.e., when di+dki9d_i + d_{k-i} \leq 9 for all ii), R(n)R(n) is a palindrome.

Proof. Without carries, the digit at position ii of R(n)R(n) is di+dkid_i + d_{k-i}. Since di+dki=dki+did_i + d_{k-i} = d_{k-i} + d_i, the digit at position ii equals the digit at position kik - i, so R(n)R(n) is a palindrome. \blacksquare

Corollary 2. Lychrel candidates arise only when carry propagation in RR repeatedly disrupts palindromic symmetry for at least LL consecutive iterations.

Theorem 3 (Carry Asymmetry Mechanism). When di+dki10d_i + d_{k-i} \geq 10 for some ii, a carry of 1 propagates to position i+1i + 1. This carry may not have a symmetric counterpart at position k(i+1)=ki1k - (i + 1) = k - i - 1, breaking the palindromic structure. Specifically, position i+1i + 1 receives a carry while position ki1k - i - 1 may not, creating asymmetric digits.

Proof. The carry from position ii adds 1 to the sum at position i+1i + 1, making it di+1+dki1+1d_{i+1} + d_{k-i-1} + 1. The symmetric position ki1k - i - 1 receives the sum dki1+di+1d_{k-i-1} + d_{i+1} (without carry, unless its own lower-order position generated a carry). Since carry propagation depends on the specific digits and proceeds left-to-right, the carry pattern at position jj need not match the carry pattern at position kjk - j. \blacksquare

Remark. Whether any true Lychrel number exists in base 10 (i.e., one that never produces a palindrome regardless of the number of iterations) remains an open problem. The number 196 is the smallest candidate, with no palindrome found after more than 10910^9 iterations.

Editorial

We inspect every starting value below 10,000 independently. For each candidate, the reverse-and-add transformation is applied repeatedly for at most 50 steps, and after each step the new value is checked for palindromicity. If no palindrome appears within those 50 iterations, the starting value is counted as a Lychrel candidate under the problem’s convention.

Pseudocode

Algorithm: Counting Lychrel Numbers Below Ten Thousand
Require: The positive integers below 10^4.
Ensure: The number of starting values that do not produce a decimal palindrome within 50 reverse-and-add steps.
1: Initialize count ← 0.
2: For each starting value n in {1, 2, ..., 9999}, set x ← n and perform at most 50 reverse-and-add iterations.
3: After each iteration, if x has become a decimal palindrome, stop and classify n as non-Lychrel.
4: If the 50-step limit is reached without producing a palindrome, increment count.
5: Return count.

Complexity Analysis

Proposition 1 (Time). The algorithm tests N1=9999N - 1 = 9999 integers, performing at most L=50L = 50 iterations each. By Corollary 1, after kk iterations starting from n<104n < 10^4 (at most 4 digits), R(k)(n)R^{(k)}(n) has at most 4+k544 + k \leq 54 digits. Each iteration computes a reversal (O(d)O(d)) and an addition (O(d)O(d)) where d54d \leq 54. The palindrome check also costs O(d)O(d). Total:

O((N1)LD)=O(9999×50×54)2.7×107,O\bigl((N - 1) \cdot L \cdot D\bigr) = O(9999 \times 50 \times 54) \approx 2.7 \times 10^7,

where D=d0+LD = d_0 + L is the maximum digit count. Since Python handles arbitrary-precision integers natively, no special big-number library is needed.

Proposition 2 (Space). O(D)=O(d0+L)=O(54)O(D) = O(d_0 + L) = O(54) for the current number during each iteration.

Answer

249\boxed{249}

Code

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

C++ project_euler/problem_055/solution.cpp
#include <bits/stdc++.h>
using namespace std;

// Arbitrary-precision addition using strings
string add(const string& a, const string& b) {
    string result;
    int carry = 0;
    int i = a.size() - 1, j = b.size() - 1;
    while (i >= 0 || j >= 0 || carry) {
        int sum = carry;
        if (i >= 0) sum += a[i--] - '0';
        if (j >= 0) sum += b[j--] - '0';
        result.push_back('0' + sum % 10);
        carry = sum / 10;
    }
    reverse(result.begin(), result.end());
    return result;
}

bool is_palindrome(const string& s) {
    int n = s.size();
    for (int i = 0; i < n / 2; i++)
        if (s[i] != s[n - 1 - i]) return false;
    return true;
}

bool is_lychrel(int n) {
    string s = to_string(n);
    for (int i = 0; i < 50; i++) {
        string rev = s;
        reverse(rev.begin(), rev.end());
        s = add(s, rev);
        if (is_palindrome(s)) return false;
    }
    return true;
}

int main() {
    int count = 0;
    for (int n = 1; n < 10000; n++) {
        if (is_lychrel(n)) count++;
    }
    cout << count << endl;
    return 0;
}