All Euler problems
Project Euler

Sum of Digits -- Experience #23

For a positive integer k, let d(k) denote the digit sum of k. Define S(n) = #{k: 0 < k < 10^n, 23 | k, d(k) = 23}. Given: S(9) = 263626, S(42) = 6,377,168,878,570,056. Find S(11^12) mod 10^9.

Source sync Apr 19, 2026
Problem #0294
Level Level 14
Solved By 1,118
Languages C++, Python
Answer 789184709
Length 328 words
linear_algebramodular_arithmeticdigit_dp

Problem Statement

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

For a positive integer \(k\), define \(d(k)\) as the sum of the digits of \(k\) in its usual decimal representation. Thus \(d(42) = 4+2 = 6\).

For a positive integer \(n\), define \(S(n)\) as the number of positive integers \(k < 10^n\) with the following properties :

  • \(k\) is divisible by \(23\) and

  • \(d(k) = 23\).

You are given that \(S(9) = 263626\) and \(S(42) = 6377168878570056\).

Find \(S(11^{12})\) and give your answer mod \(10^9\).

Problem 294: Sum of Digits — Experience #23

Mathematical Foundation

Theorem 1 (Digit DP State Space). The number of integers 0k<10n0 \leq k < 10^n satisfying d(k)=23d(k) = 23 and 23k23 \mid k equals the (s=23,r=0)(s=23, r=0) entry of the vector Tnv0T^n \mathbf{v}_0, where TT is a 552×552552 \times 552 transition matrix and v0\mathbf{v}_0 is the initial state vector with a 11 at position (s=0,r=0)(s=0, r=0).

Proof. We encode each partial number after processing ii digits (from most significant to least significant) by the state (s,r)(s, r) where s{0,1,,23}s \in \{0, 1, \ldots, 23\} is the running digit sum and r{0,1,,22}r \in \{0, 1, \ldots, 22\} is the running value modulo 23. The state space has 24×23=55224 \times 23 = 552 elements.

When we append digit d{0,1,,9}d \in \{0, 1, \ldots, 9\}, the state transitions as:

(s,r)d(s+d,  (10r+d)mod23)provided s+d23.(s, r) \xrightarrow{d} (s + d,\; (10r + d) \bmod 23) \quad \text{provided } s + d \leq 23.

The transition matrix TT has entry T(s,r),(s,r)=#{d{0,,9}:s=s+d,  r=(10r+d)mod23}T_{(s', r'), (s, r)} = \#\{d \in \{0,\ldots,9\} : s' = s + d,\; r' = (10r + d) \bmod 23\}. Starting from state (0,0)(0, 0) and applying TT exactly nn times, the count of valid kk is the entry at state (23,0)(23, 0). Since d(0)=023d(0) = 0 \neq 23, the case k=0k = 0 is automatically excluded. \square

Theorem 2 (Matrix Exponentiation). For any n×nn \times n matrix TT and positive integer NN, the matrix power TNT^N can be computed in O(n3logN)O(n^3 \log N) arithmetic operations via repeated squaring.

Proof. Write NN in binary: N=i=0log2Nbi2iN = \sum_{i=0}^{\lfloor \log_2 N \rfloor} b_i 2^i. Compute T,T2,T4,,T2log2NT, T^2, T^4, \ldots, T^{2^{\lfloor \log_2 N \rfloor}} by successive squaring (log2N\lfloor \log_2 N \rfloor matrix multiplications). Then TN=i:bi=1T2iT^N = \prod_{i : b_i = 1} T^{2^i}, requiring at most log2N\lfloor \log_2 N \rfloor additional matrix multiplications. Each matrix multiplication costs O(n3)O(n^3). \square

Lemma 1 (Modular Computation). Since all entries of TT are non-negative integers and we compute modulo 10910^9, all intermediate results remain in [0,109)[0, 10^9) and the final result equals S(1112)mod109S(11^{12}) \bmod 10^9.

Proof. The entries of TnT^n count paths in the state graph, which are non-negative integers. By properties of modular arithmetic, (AB)modm=((Amodm)(Bmodm))modm(A \cdot B) \bmod m = ((A \bmod m) \cdot (B \bmod m)) \bmod m, so reducing modulo 10910^9 at each multiplication step yields the correct result modulo 10910^9. \square

Editorial

S(n) = count of positive integers k < 10^n with 23 | k and digit sum d(k) = 23. Find S(11^12) mod 10^9. Approach: Matrix exponentiation on the digit DP transition matrix. State: (digit_sum, value mod 23), dimension 24 * 23 = 552. We build 552 x 552 transition matrix T. We then states indexed as (s, r) -> s * 23 + r. Finally, compute T^n mod MOD via repeated squaring.

Pseudocode

Build 552 x 552 transition matrix T
States indexed as (s, r) -> s * 23 + r
Compute T^n mod MOD via repeated squaring
Answer is entry (23*23 + 0, 0*23 + 0) = (529, 0)

Complexity Analysis

  • Time: O(5523log2(1112))O(552^3 \cdot \log_2(11^{12})). We have log2(1112)=12log2(11)41.5\log_2(11^{12}) = 12 \log_2(11) \approx 41.5, so approximately 42 matrix squarings. Each matrix multiplication costs 55231.68×108552^3 \approx 1.68 \times 10^8 operations. Total: 42×1.68×1087.1×109\approx 42 \times 1.68 \times 10^8 \approx 7.1 \times 10^9 modular multiplications.
  • Space: O(5522)=O(304,704)O(552^2) = O(304{,}704) for storing the matrix, i.e., a few megabytes.

Answer

789184709\boxed{789184709}

Code

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

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

typedef long long ll;
typedef vector<vector<ll>> Matrix;

const ll MOD = 1000000000LL;
const int S_MAX = 24; // digit sums 0..23
const int R_MAX = 23; // remainders mod 23: 0..22
const int DIM = S_MAX * R_MAX; // 552

// State encoding: (s, r) -> s * R_MAX + r
int encode(int s, int r) { return s * R_MAX + r; }

Matrix mat_mul(const Matrix& A, const Matrix& B) {
    int n = A.size();
    Matrix C(n, vector<ll>(n, 0));
    for (int i = 0; i < n; i++)
        for (int k = 0; k < n; k++) {
            if (A[i][k] == 0) continue;
            for (int j = 0; j < n; j++) {
                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;
            }
        }
    return C;
}

Matrix mat_pow(Matrix M, ll p) {
    int n = M.size();
    Matrix R(n, vector<ll>(n, 0));
    for (int i = 0; i < n; i++) R[i][i] = 1; // identity
    while (p > 0) {
        if (p & 1) R = mat_mul(R, M);
        M = mat_mul(M, M);
        p >>= 1;
    }
    return R;
}

int main() {
    // Build transition matrix
    Matrix T(DIM, vector<ll>(DIM, 0));
    for (int s = 0; s < S_MAX; s++) {
        for (int r = 0; r < R_MAX; r++) {
            for (int d = 0; d <= 9; d++) {
                int ns = s + d;
                if (ns >= S_MAX) continue;
                int nr = (10 * r + d) % R_MAX;
                int from = encode(s, r);
                int to = encode(ns, nr);
                T[to][from] = (T[to][from] + 1) % MOD;
            }
        }
    }

    // Compute T^n where n = 11^12
    // 11^12 = 3138428376721
    ll n = 1;
    for (int i = 0; i < 12; i++) n *= 11;
    // n = 3138428376721

    Matrix Tn = mat_pow(T, n);

    // Answer: Tn[encode(23, 0)][encode(0, 0)]
    ll ans = Tn[encode(23, 0)][encode(0, 0)];
    cout << ans << endl;

    return 0;
}