All Euler problems
Project Euler

Factorial Digit Sum

Let S(m) denote the sum of the decimal digits of a positive integer m. Compute S(100!).

Source sync May 21, 2026
Problem #0020
Level Level 00
Solved By 214,580
Languages C++, Python
Answer 648
Length 351 words
modular_arithmeticanalytic_mathnumber_theory

Problem Statement

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

\(n!\) means \(n \times (n - 1) \times \cdots \times 3 \times 2 \times 1\).

For example, \(10! = 10 \times 9 \times \cdots \times 3 \times 2 \times 1 = 3628800\),

and the sum of the digits in the number \(10!\) is \(3 + 6 + 2 + 8 + 8 + 0 + 0 = 27\).

Find the sum of the digits in the number \(100!\).

Problem 20: Factorial Digit Sum

Mathematical Development

Definition 1 (Digit sum). For a positive integer m=∑k=0d−1ak⋅10km = \sum_{k=0}^{d-1} a_k \cdot 10^k with digits ak∈{0,…,9}a_k \in \{0, \ldots, 9\} and ad−1≠0a_{d-1} \ne 0, define S(m)=∑k=0d−1akS(m) = \sum_{k=0}^{d-1} a_k.

Theorem 1 (Digit count of n!n!). The number of digits of n!n! is

d(n!)=⌊log⁡10(n!)⌋+1,where log⁡10(n!)=∑k=1nlog⁡10(k).d(n!) = \lfloor \log_{10}(n!) \rfloor + 1, \quad \text{where } \log_{10}(n!) = \sum_{k=1}^{n} \log_{10}(k).

Proof. A positive integer mm has ⌊log⁡10m⌋+1\lfloor \log_{10} m \rfloor + 1 digits. Applying the multiplicative property of logarithms: log⁡10(n!)=log⁡10 ⁣(∏k=1nk)=∑k=1nlog⁡10(k)\log_{10}(n!) = \log_{10}\!\bigl(\prod_{k=1}^{n} k\bigr) = \sum_{k=1}^{n} \log_{10}(k). □\square

Corollary 1. By Stirling’s approximation, log⁡10(n!)≈nlog⁡10(n/e)+12log⁡10(2πn)\log_{10}(n!) \approx n \log_{10}(n/e) + \frac{1}{2}\log_{10}(2\pi n). For n=100n = 100: log⁡10(100!)≈157.97\log_{10}(100!) \approx 157.97, so d(100!)=158d(100!) = 158.

Theorem 2 (Digit sum congruence). For every positive integer mm, S(m)≡m(mod9)S(m) \equiv m \pmod{9}.

Proof. Since 10≡1(mod9)10 \equiv 1 \pmod{9}, we have 10k≡1(mod9)10^k \equiv 1 \pmod{9} for all k≥0k \ge 0, hence m=∑ak⋅10k≡∑ak=S(m)(mod9)m = \sum a_k \cdot 10^k \equiv \sum a_k = S(m) \pmod{9}. □\square

Theorem 3 (Legendre’s formula). For a prime pp and positive integer nn, the pp-adic valuation of n!n! is

νp(n!)=∑i=1∞⌊npi⌋.\nu_p(n!) = \sum_{i=1}^{\infty} \left\lfloor \frac{n}{p^i} \right\rfloor.

Proof. Each factor k∈{1,…,n}k \in \{1, \ldots, n\} contributes νp(k)\nu_p(k) to νp(n!)\nu_p(n!). The number of multiples of pip^i in {1,…,n}\{1, \ldots, n\} is ⌊n/pi⌋\lfloor n/p^i \rfloor. By inclusion, νp(n!)=∑k=1nνp(k)=∑i=1∞⌊n/pi⌋\nu_p(n!) = \sum_{k=1}^{n} \nu_p(k) = \sum_{i=1}^{\infty} \lfloor n/p^i \rfloor. (The sum is finite since ⌊n/pi⌋=0\lfloor n/p^i \rfloor = 0 for pi>np^i > n.) □\square

Proposition 1 (100!≡0(mod9)100! \equiv 0 \pmod{9}). We have ν3(100!)=⌊100/3⌋+⌊100/9⌋+⌊100/27⌋+⌊100/81⌋=33+11+3+1=48\nu_3(100!) = \lfloor 100/3 \rfloor + \lfloor 100/9 \rfloor + \lfloor 100/27 \rfloor + \lfloor 100/81 \rfloor = 33 + 11 + 3 + 1 = 48.

Proof. Direct application of Theorem 3 with p=3p = 3. Since ν3(100!)=48≥2\nu_3(100!) = 48 \ge 2, we have 9∣100!9 \mid 100!, and by Theorem 2, S(100!)≡0(mod9)S(100!) \equiv 0 \pmod{9}. □\square

Verification. S(100!)=648=72×9S(100!) = 648 = 72 \times 9, confirming 648≡0(mod9)648 \equiv 0 \pmod{9}.

Theorem 4 (Trailing zeros of n!n!). The number of trailing zeros of n!n! is ν5(n!)=∑i=1∞⌊n/5i⌋\nu_5(n!) = \sum_{i=1}^{\infty} \lfloor n/5^i \rfloor.

Proof. A trailing zero corresponds to a factor of 10=2×510 = 2 \times 5. Since ν2(n!)≥ν5(n!)\nu_2(n!) \ge \nu_5(n!) for all n≥1n \ge 1 (as multiples of 2 are more frequent than multiples of 5), the count of trailing zeros equals min⁡ ⁣(ν2(n!),ν5(n!))=ν5(n!)\min\!\bigl(\nu_2(n!), \nu_5(n!)\bigr) = \nu_5(n!). □\square

Corollary 2. ν5(100!)=⌊100/5⌋+⌊100/25⌋=20+4=24\nu_5(100!) = \lfloor 100/5 \rfloor + \lfloor 100/25 \rfloor = 20 + 4 = 24. Hence 100!100! has 24 trailing zeros, which contribute nothing to S(100!)S(100!).

Proposition 2 (Bounds on S(100!)S(100!)). Since 100!100! has 158 digits:

1≤S(100!)≤9×158=1422.1 \le S(100!) \le 9 \times 158 = 1422.

The 134 non-trailing-zero digits have an average value near 4.54.5, giving a heuristic estimate ≈603\approx 603. The actual value 648648 is modestly above this estimate.

Proof. Lower bound: at least one digit is nonzero. Upper bound: each digit ≤9\le 9. □\square

Editorial

We form n!n! by multiplying the integers from 2 through nn, then extract its decimal digits and add them. The second phase repeatedly takes the last digit with a modulo-10 operation and removes it with integer division until no digits remain. This is sufficient because every digit of n!n! is processed exactly once.

Pseudocode

Algorithm: Digit Sum of a Factorial
Require: An integer n ≥ 1.
Ensure: The sum of the decimal digits of n!.
1: Initialize F ← 1.
2: For each k in {2, 3, ..., n}, update F ← F · k.
3: Compute the decimal digit expansion of F.
4: Return the sum of those digits.

Complexity Analysis

Proposition 3 (Time complexity). The algorithm runs in O(n2log⁡n)O(n^2 \log n) time.

Proof. Let d=d(n!)=Θ(nlog⁡n)d = d(n!) = \Theta(n \log n) by Stirling’s approximation. At step kk, the running product has Θ(klog⁡k)\Theta(k \log k) digits, and multiplying it by kk (a number with O(log⁡n)O(\log n) digits) costs O(klog⁡k)O(k \log k) using schoolbook multiplication. The total time is:

∑k=2nO(klog⁡k)=O ⁣(log⁡n∑k=2nk)=O(n2log⁡n).\sum_{k=2}^{n} O(k \log k) = O\!\left(\log n \sum_{k=2}^{n} k\right) = O(n^2 \log n).

The final digit-extraction loop runs in O(d)=O(nlog⁡n)O(d) = O(n \log n), which is dominated by the multiplication phase. □\square

Proposition 4 (Space complexity). The algorithm uses Θ(nlog⁡n)\Theta(n \log n) space.

Proof. The intermediate product requires O(d)=O(nlog⁡n)O(d) = O(n \log n) digits of storage. □\square

Answer

648\boxed{648}

Code

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

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

int main() {
    vector<int> digits = {1};

    for (int n = 2; n <= 100; n++) {
        int carry = 0;
        for (int j = 0; j < (int)digits.size(); j++) {
            int val = digits[j] * n + carry;
            digits[j] = val % 10;
            carry = val / 10;
        }
        while (carry > 0) {
            digits.push_back(carry % 10);
            carry /= 10;
        }
    }

    int sum = 0;
    for (int d : digits) sum += d;
    cout << sum << endl;
    return 0;
}