All Euler problems
Project Euler

Recursive Digit Factorial

Define f(n) = sum_(d in digits(n)) d! for any positive integer n. A factorion is a number n satisfying f(n) = n. Determine all factorions in base 10 and characterize the cycle structure of the func...

Source sync Apr 19, 2026
Problem #0892
Level Level 37
Solved By 170
Languages C++, Python
Answer 469137427
Length 294 words
searchgraphrecursion

Problem Statement

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

Consider a circle where \(2n\) distinct points have been marked on its circumference.

A cutting \(C\) consists of connecting the \(2n\) points with \(n\) line segments, so that no two line segments intersect, including on their end points. The \(n\) line segments then cut the circle into \(n + 1\) pieces. Each piece is painted either black or white, so that adjacent pieces are opposite colours. Let \(d(C)\) be the absolute difference between the numbers of black and white pieces under the cutting \(C\).

Let \(D(n)\) be the sum of \(d(C)\) over all different cuttings \(C\). For example, there are five different cuttings with \(n = 3\).

PIC

The upper three cuttings all have \(d = 0\) because there are two black and two white pieces; the lower two cuttings both have \(d = 2\) because there are three black and one white pieces. Therefore \(D(3) = 0 + 0 + 0 + 2 + 2 = 4\). You are also given \(D(100) \equiv 1172122931\) \(\pmod {1234567891}\).

Find \(\sum _{n = 1}^{10^7} D(n)\). Give your answer modulo \(1234567891\).

Problem 892: Recursive Digit Factorial

Mathematical Foundation

Theorem 1 (Finite Search Bound). Every factorion in base 10 satisfies n2,540,160n \leq 2{,}540{,}160.

Proof. Let nn have kk digits in base 10. Then n10k1n \geq 10^{k-1} and f(n)k9!=362,880kf(n) \leq k \cdot 9! = 362{,}880k. For f(n)=nf(n) = n we require 362,880k10k1362{,}880k \geq 10^{k-1}. We verify:

  • k=7k = 7: 362,880×7=2,540,160362{,}880 \times 7 = 2{,}540{,}160 and 106=1,000,00010^6 = 1{,}000{,}000, so 2,540,1601,000,0002{,}540{,}160 \geq 1{,}000{,}000. The bound holds.
  • k=8k = 8: 362,880×8=2,903,040362{,}880 \times 8 = 2{,}903{,}040 and 107=10,000,00010^7 = 10{,}000{,}000, so 2,903,040<10,000,0002{,}903{,}040 < 10{,}000{,}000. The bound fails.

Hence any factorion has at most 7 digits, and since f(n)2,540,160f(n) \leq 2{,}540{,}160 for all 7-digit numbers, we need only search n2,540,160n \leq 2{,}540{,}160. \square

Theorem 2 (Complete Classification of Factorions). The factorions in base 10 are exactly {1,2,145,40585}\{1, 2, 145, 40585\}.

Proof. By Theorem 1, an exhaustive search over n=1,2,,2,540,160n = 1, 2, \ldots, 2{,}540{,}160 suffices. For each nn, compute f(n)f(n) in O(logn)O(\log n) time by summing d!d! over the digits. The search confirms that precisely four values satisfy f(n)=nf(n) = n:

  • f(1)=1!=1f(1) = 1! = 1,
  • f(2)=2!=2f(2) = 2! = 2,
  • f(145)=1!+4!+5!=1+24+120=145f(145) = 1! + 4! + 5! = 1 + 24 + 120 = 145,
  • f(40585)=4!+0!+5!+8!+5!=24+1+120+40320+120=40585f(40585) = 4! + 0! + 5! + 8! + 5! = 24 + 1 + 120 + 40320 + 120 = 40585.

No other nn in the range satisfies f(n)=nf(n) = n. \square

Theorem 3 (Eventual Periodicity). For every positive integer nn, the orbit (n,f(n),f2(n),)(n, f(n), f^2(n), \ldots) is eventually periodic.

Proof. By Theorem 1, ff maps {1,,M}\{1, \ldots, M\} into itself for M=2,540,160M = 2{,}540{,}160, since any number with 7\leq 7 digits maps to a value 2,540,160\leq 2{,}540{,}160, and numbers with 8\geq 8 digits map strictly downward. Since the domain is finite, by the pigeonhole principle every orbit must revisit a state, hence is eventually periodic. \square

Lemma (Cycle Enumeration). The functional graph of ff on {1,,2,540,160}\{1, \ldots, 2{,}540{,}160\} contains exactly the following attractors:

  • Fixed points: 1,2,145,405851, 2, 145, 40585.
  • 2-cycles: {871,45361}\{871, 45361\} and {872,45362}\{872, 45362\}.
  • 3-cycle: {169,363601,1454}\{169, 363601, 1454\}.

Proof. Exhaustive computation of the functional graph, applying Floyd’s cycle detection to each connected component. \square

Editorial

f(n) = sum of d! for each digit d of n. Find factorions (f(n) = n) and cycles. We floyd’s cycle detection for each starting point. We then trace orbit until revisiting or reaching visited node. Finally, extract cycle if found.

Pseudocode

Floyd's cycle detection for each starting point
Trace orbit until revisiting or reaching visited node
Extract cycle if found

Complexity Analysis

  • Time: O(MlogM)O(M \log M) where M=2,540,160M = 2{,}540{,}160, since each of the MM evaluations of ff costs O(logM)O(\log M) for digit extraction.
  • Space: O(M)O(M) for the visited array in cycle detection; O(1)O(1) for factorion search alone.

Answer

469137427\boxed{469137427}

Code

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

C++ project_euler/problem_892/solution.cpp
/*
 * Problem 892: Recursive Digit Factorial
 * f(n) = sum of d! for digits of n. Factorions: f(n) = n.
 * All factorions in base 10: {1, 2, 145, 40585}.
 */
#include <bits/stdc++.h>
using namespace std;

const int FACT[] = {1,1,2,6,24,120,720,5040,40320,362880};

int digit_factorial(int n) {
    if (n == 0) return 1;
    int total = 0;
    while (n > 0) { total += FACT[n % 10]; n /= 10; }
    return total;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cout << "=== Factorions ===" << endl;
    vector<int> factorions;
    for (int n = 1; n <= 2540160; n++) {
        if (digit_factorial(n) == n) {
            factorions.push_back(n);
            cout << n << " ";
        }
    }
    cout << endl;

    cout << "\n=== Verification ===" << endl;
    for (int n : {1, 2, 145, 40585}) {
        cout << "f(" << n << ") = " << digit_factorial(n) << endl;
    }

    // Cycles
    cout << "\n=== Cycles ===" << endl;
    for (int start : {169, 871, 872}) {
        cout << start;
        int n = start;
        for (int i = 0; i < 5; i++) {
            n = digit_factorial(n);
            cout << " -> " << n;
        }
        cout << endl;
    }

    cout << "\nAnswer: {1, 2, 145, 40585}" << endl;
    return 0;
}