All Euler problems
Project Euler

Finding Numbers for Which the Sum of the Squares of the Digits Is a Perfect Square

For a positive integer n, let f(n) denote the sum of the squares of the digits of n in base 10. Find the last nine digits of sum_(0 < n < 10^(20 f(n) is a perfect square)) n.

Source sync Apr 19, 2026
Problem #0171
Level Level 08
Solved By 3,272
Languages C++, Python
Answer 142989277
Length 381 words
modular_arithmeticdigit_dpdynamic_programming

Problem Statement

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

For a positive integer \(n\), let \(f(n)\) be the sum of the squares of the digits (in base \(10\)) of \(n\), e.g. \begin {align*} f(3) &= 3^2 = 9,\\ f(25) &= 2^2 + 5^2 = 4 + 25 = 29,\\ f(442) &= 4^2 + 4^2 + 2^2 = 16 + 16 + 4 = 36\\ \end {align*}

Find the last nine digits of the sum of all \(n\), \(0 \lt n \lt 10^{20}\), such that \(f(n)\) is a perfect square.

Problem 171: Finding Numbers for Which the Sum of the Squares of the Digits Is a Perfect Square

Mathematical Development

Definition 1. For nn with base-10 digits d1d2dDd_1 d_2 \cdots d_D, define f(n)=i=1Ddi2f(n) = \sum_{i=1}^{D} d_i^2.

Theorem 1 (Digit-square-sum bound). For any non-negative integer nn representable with at most DD decimal digits, f(n)81Df(n) \leq 81D. Consequently, the set of attainable perfect-square values of ff is {j2:1j81D}\{j^2 : 1 \leq j \leq \lfloor\sqrt{81D}\rfloor\}.

Proof. Each digit di{0,1,,9}d_i \in \{0,1,\ldots,9\} satisfies di292=81d_i^2 \leq 9^2 = 81. Summing over DD digits yields f(n)81Df(n) \leq 81D. The perfect squares in {1,2,,M}\{1,2,\ldots,M\} are exactly {12,22,,M2}\{1^2,2^2,\ldots,\lfloor\sqrt{M}\rfloor^2\}, giving the claimed set. \square

Corollary 1. For D=20D = 20, we have f(n)1620f(n) \leq 1620 and 1620=40\lfloor\sqrt{1620}\rfloor = 40. The target set of perfect-square sums is {1,4,9,,1600}\{1, 4, 9, \ldots, 1600\}.

Lemma 1 (Digit-append identity). Let S\mathcal{S} be any set of non-negative integers and let d{0,1,,9}d \in \{0,1,\ldots,9\}. Then

xS(10x+d)=10xSx+dS.\sum_{x \in \mathcal{S}} (10x + d) = 10\sum_{x \in \mathcal{S}} x + d \cdot |\mathcal{S}|.

Proof. By linearity of finite sums:

xS(10x+d)=10xSx+xSd=10xSx+dS.\sum_{x \in \mathcal{S}} (10x + d) = 10 \sum_{x \in \mathcal{S}} x + \sum_{x \in \mathcal{S}} d = 10 \sum_{x \in \mathcal{S}} x + d \cdot |\mathcal{S}|. \quad \square

Theorem 2 (Digit DP correctness). Define the following quantities for k0k \geq 0 and 0s81D0 \leq s \leq 81D:

  • C[k][s]C[k][s] := the number of kk-character strings over {0,1,,9}\{0,1,\ldots,9\} whose digit-square-sum equals ss.
  • T[k][s]T[k][s] := the sum, modulo 10910^9, of the numerical values of all such strings.

Initialize C[0][0]=1C[0][0] = 1 and T[0][0]=0T[0][0] = 0, with all other entries zero. The recurrence for appending digit d{0,,9}d \in \{0,\ldots,9\} is:

C[k+1][s+d2]+=C[k][s],T[k+1][s+d2]+=10T[k][s]+dC[k][s].C[k+1][s + d^2] \mathrel{+}= C[k][s], \qquad T[k+1][s + d^2] \mathrel{+}= 10 \cdot T[k][s] + d \cdot C[k][s].

Then the answer to the problem is

j=140T[20][j2](mod109).\sum_{j=1}^{40} T[20][j^2] \pmod{10^9}.

Proof. We represent every integer n{0,1,,10201}n \in \{0, 1, \ldots, 10^{20}-1\} uniquely as a 20-character zero-padded decimal string. The DP constructs these strings one character at a time, left to right. At layer kk, C[k][s]C[k][s] counts strings of length kk with digit-square-sum ss, and T[k][s]T[k][s] holds their aggregate numerical value modulo 10910^9.

The correctness of the transition for TT follows from Lemma 1: when we extend every string xx in S={x:length k,  f(x)=s}\mathcal{S} = \{x : \text{length } k,\; f(x) = s\} by appending digit dd, the new numerical value of each extended string is 10x+d10x + d, and the new digit-square-sum is s+d2s + d^2. The sum over S\mathcal{S} of these new values is 10T[k][s]+dC[k][s]10 \cdot T[k][s] + d \cdot C[k][s], as required.

After processing all D=20D = 20 positions, T[20][j2]T[20][j^2] accumulates the sum of all 20-character strings with digit-square-sum j2j^2. Summing over j=1,,40j = 1, \ldots, 40 yields the desired total modulo 10910^9.

Finally, the string 00000\cdots0 representing n=0n = 0 has f(0)=0f(0) = 0, which is a perfect square (0=020 = 0^2). However, since n=0n = 0 contributes 00 to the sum, the exclusion n>0n > 0 in the problem statement requires no correction. \square

Editorial

Is a Perfect Square Find the last nine digits of the sum of all n, 0 < n < 10^20, such that f(n) = sum of squares of digits of n is a perfect square. Method: Digit DP tracking (count, value_sum) keyed by digit-square-sum.

Pseudocode

MOD = 10^9
S_MAX = 1620

C[0..S_MAX] = 0; T[0..S_MAX] = 0
C[0] = 1

For k from 1 to 20:
    C'[0..S_MAX] = 0; T'[0..S_MAX] = 0
    For s from 0 to S_MAX:
        If C[s] == 0 then continue
        For d from 0 to 9:
            s' = s + d*d
            if s' > S_MAX: break // digits are in order, so d^2 increases
            C'[s'] += C[s]
            T'[s'] = (T'[s'] + 10*T[s] + d*C[s]) mod MOD
    C = C'; T = T'

answer = 0
For j from 1 to 40:
    answer = (answer + T[j*j]) mod MOD
Return answer

Complexity Analysis

  • Time: The triple loop executes DSmax10D \cdot S_{\max} \cdot 10 iterations in the worst case. With D=20D = 20 and Smax=1620S_{\max} = 1620, this gives 20×1621×10=324,20020 \times 1621 \times 10 = 324{,}200 operations. Hence O(DSmax)O(D \cdot S_{\max}).
  • Space: Two arrays of size Smax+1=1621S_{\max} + 1 = 1621 suffice (rolling-array technique), giving O(Smax)O(S_{\max}).

Answer

142989277\boxed{142989277}

Code

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

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

int main() {
    /*
     * Problem 171: Last 9 digits of sum of all n in (0, 10^20) with
     * f(n) = sum of squared digits being a perfect square.
     *
     * Digit DP: track (count, value_sum) keyed by digit-square-sum.
     */
    const long long MOD = 1000000000LL;
    const int D = 20;
    const int SMAX = D * 81; // 1620

    vector<long long> cnt(SMAX + 1, 0), tot(SMAX + 1, 0);
    cnt[0] = 1;

    for (int k = 0; k < D; k++) {
        vector<long long> nc(SMAX + 1, 0), nt(SMAX + 1, 0);
        for (int s = 0; s <= SMAX; s++) {
            if (cnt[s] == 0) continue;
            for (int d = 0; d <= 9; d++) {
                int ns = s + d * d;
                if (ns > SMAX) break;
                nc[ns] = (nc[ns] + cnt[s]) % MOD;
                nt[ns] = (nt[ns] + 10 * tot[s] % MOD + (long long)d * (cnt[s] % MOD)) % MOD;
            }
        }
        cnt = nc;
        tot = nt;
    }

    long long ans = 0;
    for (int j = 1; j * j <= SMAX; j++)
        ans = (ans + tot[j * j]) % MOD;

    cout << ans << endl;
    return 0;
}