All Euler problems
Project Euler

Square Digit Chains

Define f(n)=sum of the squares of the decimal digits of n. Starting from a positive integer n, repeatedly apply f. Every chain eventually enters a cycle. We must count how many starting numbers n<1...

Source sync Apr 19, 2026
Problem #0092
Level Level 02
Solved By 45,884
Languages C++, Python
Answer 8581146
Length 448 words
dynamic_programminglinear_algebrasequence

Problem Statement

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

A number chain is created by continuously adding the square of the digits in a number to form a new number until it has been seen before.

For example, \begin {align*} &44 \to 32 \to 13 \to 10 \to \mathbf 1 \to \mathbf 1\\ &85 \to \mathbf {89} \to 145 \to 42 \to 20 \to 4 \to 16 \to 37 \to 58 \to \mathbf {89} \end {align*}

Therefore any chain that arrives at \(1\) or \(89\) will become stuck in an endless loop. What is most amazing is that EVERY starting number will eventually arrive at \(1\) or \(89\).

How many starting numbers below ten million will arrive at \(89\)?

Problem 92: Square Digit Chains

Step 1: Reduce the state space

If n<107n<10^7, then nn has at most 77 digits, so

f(n)792=567.f(n)\le 7\cdot 9^2 = 567.

Thus after one application of ff, every chain enters the finite set

{0,1,2,,567}.\{0,1,2,\dots,567\}.

Therefore the eventual destination of nn depends only on the value f(n)f(n). In particular, if we know for each s{1,,567}s\in\{1,\dots,567\} whether repeated application of ff reaches 11 or 8989, then we only need to count how many numbers below 10710^7 have initial digit-square-sum equal to such an ss.

Step 2: Count numbers by their digit-square-sum

Every number 0n<1070\le n<10^7 has a unique 7-digit representation with leading zeros allowed. So it is equivalent to count 7-digit strings

d1d2d7,di{0,1,,9},d_1d_2\cdots d_7,\qquad d_i\in\{0,1,\dots,9\},

by the value

d12+d22++d72.d_1^2+d_2^2+\cdots+d_7^2.

Let Ck(s)C_k(s) be the number of length-kk digit strings whose digit-square-sum is ss. Then

  • C0(0)=1C_0(0)=1,
  • C0(s)=0C_0(s)=0 for s0s\ne 0,
  • and for k0k\ge 0,
Ck+1(s)=d=09Ck(sd2),C_{k+1}(s)=\sum_{d=0}^{9} C_k(s-d^2),

where terms with negative index are interpreted as 00.

This recurrence is immediate: to build a (k+1)(k+1)-digit string with total square-sum ss, choose its last digit dd, and the first kk digits must contribute sd2s-d^2.

After computing C7(s)C_7(s) for all 0s5670\le s\le 567, the answer is

0s567s89C7(s),\sum_{\substack{0\le s\le 567\\ s\leadsto 89}} C_7(s),

where s89s\leadsto 89 means the chain starting from ss eventually reaches 8989.

The all-zero string contributes only to s=0s=0, and 00 does not reach 8989, so it does not affect the final count.

Why only 1 and 89 matter

Since every chain enters the finite set {1,,567}\{1,\dots,567\}, every orbit is eventually periodic. A direct computation on this finite set shows that the only periodic attractors are

111\to 1

and

891454220416375889.89\to 145\to 42\to 20\to 4\to 16\to 37\to 58\to 89.

Hence each starting value below 10710^7 ends at either 11 or 8989.

Editorial

The crucial reduction is that numbers below 10710^7 collapse after one move into the tiny state space {0,,567}\{0,\dots,567\}. So instead of following ten million chains separately, we only need to know which of those 568 sums eventually fall into the 8989-cycle.

Once those destinations are known, the counting part becomes a digit DP. We treat every number below 10710^7 as a 7-digit string with leading zeros and count how many such strings produce each possible digit-square-sum. That explores the search space by digit choices rather than by raw integers. The final answer is obtained by summing the DP counts for exactly those sums whose chains terminate at 8989.

Pseudocode

Compute, for every sum $s$ from 1 to 567, whether repeated digit-square steps end at $89$.

Initialize a DP table for digit strings with $dp[0]=1$.

Repeat for 7 digit positions:
    Create a fresh table of counts
    For each current sum and its number of realizations:
        For each possible next digit from 0 to 9:
            Update the count for the new square-digit-sum
    Replace the old table with the new one

Add the final counts for all sums whose destination is $89$.
Return that total.

Correctness

Theorem. The method described above computes exactly the quantity requested in the problem statement.

Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer. \square

Complexity Analysis

The state space for the DP has

  • 77 digit positions,
  • 568568 possible sums,
  • 1010 digit choices.

So the running time is

O(756810),O(7\cdot 568\cdot 10),

and the memory usage is

O(568).O(568).

In other words, this is a tiny constant-size computation.

Answer

8581146\boxed{8581146}

Code

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

C++ project_euler/problem_092/solution.cpp
#include <cassert>
#include <iostream>
#include <vector>

int digit_square_sum(int n) {
    int s = 0;
    while (n > 0) {
        int d = n % 10;
        s += d * d;
        n /= 10;
    }
    return s;
    return s;
}

bool ends_at_89(int n) {
    while (n != 1 && n != 89) {
        n = digit_square_sum(n);
    }
    return n == 89;
}

long long solve() {
    const int digits = 7;
    const int max_sum = digits * 81;

    std::vector<bool> destinations(max_sum + 1, false);
    for (int s = 1; s <= max_sum; ++s) {
        destinations[s] = ends_at_89(s);
    }

    std::vector<long long> dp(max_sum + 1, 0);
    dp[0] = 1;

    for (int pos = 0; pos < digits; ++pos) {
        std::vector<long long> next_dp(max_sum + 1, 0);
        for (int sum = 0; sum <= max_sum; ++sum) {
            if (dp[sum] == 0) {
                continue;
            }
            for (int digit = 0; digit <= 9; ++digit) {
                next_dp[sum + digit * digit] += dp[sum];
            }
        }
        dp = next_dp;
    }

    long long answer = 0;
    for (int s = 0; s <= max_sum; ++s) {
        if (destinations[s]) {
            answer += dp[s];
        }
    }
    return answer;
}

int main() {
    const long long answer = solve();
    assert(answer == 8581146);
    std::cout << answer << '\n';
    return 0;
}