All Euler problems
Project Euler

Multiplicative Persistence

The multiplicative persistence of n is the number of times you must multiply the digits of n until reaching a single digit. Find the sum of all n < 10^7 with multiplicative persistence exactly 4.

Source sync Apr 19, 2026
Problem #0919
Level Level 31
Solved By 275
Languages C++, Python
Answer 134222859969633
Length 421 words
modular_arithmeticdynamic_programmingdigit_dp

Problem Statement

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

We call a triangle fortunate if it has integral sides and at least one of its vertices has the property that the distance from it to the triangle’s orthocentre is exactly half the distance from the same vertex to the triangle’s circumcentre.

PIC

Triangle \(ABC\) above is an example of a fortunate triangle with sides \((6,7,8)\). The distance from the vertex \(C\) to the circumcentre \(O\) is \(\approx 4.131182\), while the distance from \(C\) to the orthocentre \(H\) is half that, at \(\approx 2.065591\).

Define \(S(P)\) to be the sum of \(a+b+c\) over all fortunate triangles with sides \(a\leq b\leq c\) and perimeter not exceeding \(P\).

For example \(S(10)=24\), arising from three triangles with sides \((1,2,2)\), \((2,3,4)\), and \((2,4,4)\). You are also given \(S(100)=3331\).

Find \(S(10^7)\).

Problem 919: Multiplicative Persistence

Mathematical Analysis

Multiplicative Digital Root Process

Definition. The multiplicative persistence mp(n)\text{mp}(n) of a positive integer nn is the number of iterations of the digit-product function f(n)=ddigits(n)df(n) = \prod_{d \in \text{digits}(n)} d needed to reach a single digit (n<10n < 10).

Examples:

  • mp(10)=1\text{mp}(10) = 1: 10010 \to 0.
  • mp(25)=2\text{mp}(25) = 2: 2510025 \to 10 \to 0.
  • mp(39)=3\text{mp}(39) = 3: 392714439 \to 27 \to 14 \to 4.
  • mp(77)=4\text{mp}(77) = 4: 77493618877 \to 49 \to 36 \to 18 \to 8.

Guaranteed Termination

Theorem. For any n10n \geq 10, f(n)<nf(n) < n. Hence the persistence is well-defined and finite.

Proof. If any digit is 0, f(n)=0<nf(n) = 0 < n. Otherwise, for a kk-digit number (k2k \geq 2), n10k1n \geq 10^{k-1} while f(n)9kf(n) \leq 9^k. Since 9k/10k1=9(9/10)k19^k/10^{k-1} = 9 \cdot (9/10)^{k-1}, this ratio is less than 9 and decreasing, so f(n)<nf(n) < n for all nn with k3k \geq 3 digits. For k=2k = 2: n10n \geq 10 and f(n)81<100f(n) \leq 81 < 100; we verify directly that f(n)81<nf(n) \leq 81 < n for n82n \geq 82, and f(n)<nf(n) < n for 10n8110 \leq n \leq 81 by inspection (the only case where f(n)f(n) could equal nn would be an Armstrong-like number, but none exist for products in 2 digits). \square

Erdos Conjecture on Persistence

Conjecture (Erdos). The multiplicative persistence of nn in base 10 is O(loglogn)O(\log \log n).

The known record-holders (smallest nn with given persistence):

PersistenceSmallest nn
00
110
225
339
477
5679
66788
768889
82677889
926888999
103778888999
11277777788888899

No number with persistence 12\geq 12 has been found.

Digit Products and 7-Smoothness

Lemma. If nn has no digit 0, then f(n)f(n) is 7-smooth (all prime factors 7\leq 7).

Proof. The digit product is a product of single digits from {1,2,,9}\{1,2,\ldots,9\}, all of which factor into primes {2,3,5,7}\{2, 3, 5, 7\}. \square

Corollary. After the first application of ff (assuming no zero digit), all subsequent orbit values are 7-smooth.

Zero Digit Shortcut

Lemma. If n10n \geq 10 has a digit 0, then mp(n)=1\text{mp}(n) = 1.

Proof. f(n)=0f(n) = 0 (single digit), done in one step. \square

This means for target persistence 4, we can skip all numbers containing digit 0.

Worked Example: Persistence 4

77f7×7=49f4×9=36f3×6=18f1×8=877 \xrightarrow{f} 7 \times 7 = 49 \xrightarrow{f} 4 \times 9 = 36 \xrightarrow{f} 3 \times 6 = 18 \xrightarrow{f} 1 \times 8 = 8

Four steps to reach a single digit, so mp(77)=4\text{mp}(77) = 4.

Distribution of Persistence Values

For n<104n < 10^4:

  • Persistence 0: 10 numbers (single digits)
  • Persistence 1: ~4825 numbers (those with a 0 digit, plus direct single-digit products)
  • Persistence 2: ~3558 numbers
  • Persistence 3: ~1484 numbers
  • Persistence 4: ~116 numbers
  • Persistence 5: ~6 numbers
  • Persistence 6: ~1 number (6788)

The density of high-persistence numbers decreases rapidly.

Proof of Correctness

  1. Termination: f(n)<nf(n) < n for n10n \geq 10, so the iteration always terminates.
  2. Exhaustiveness: We check every n[10,107)n \in [10, 10^7).
  3. Digit extraction: Standard modular arithmetic correctly extracts digits.
  4. Summation: We accumulate nn (not f(n)f(n)) when mp(n)=4\text{mp}(n) = 4.

Complexity Analysis

  • Per-number cost: O(lognk)O(\log n \cdot k) where k11k \leq 11 is the persistence.
  • Total: O(NlogN)O(N \log N) for N=107N = 10^7.
  • Space: O(1)O(1) extra (no memoization needed).

Answer

134222859969633\boxed{134222859969633}

Code

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

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

/*
 * Problem 919: Multiplicative Persistence
 *
 * Find the sum of all n < 10^7 with multiplicative persistence exactly 4.
 *
 * Multiplicative persistence: repeatedly replace n by the product of its
 * digits until reaching a single digit. Count the steps.
 *
 * Key facts:
 *   - f(n) < n for n >= 10, so persistence is finite.
 *   - Numbers with digit 0 have persistence 1 (f(n) = 0 immediately).
 *   - Erdos conjecture: persistence = O(log log n).
 *   - Record: persistence 11 at n = 277777788888899.
 *
 * Complexity: O(N * log N) time, O(1) space.
 */

int digit_product(int n) {
    int p = 1;
    while (n > 0) {
        p *= n % 10;
        n /= 10;
    }
    return p;
}

int persistence(int n) {
    int c = 0;
    while (n >= 10) {
        n = digit_product(n);
        c++;
    }
    return c;
}

int main() {
    const int N = 10000000;
    const int TARGET = 4;
    long long total = 0;

    for (int n = 10; n < N; n++) {
        if (persistence(n) == TARGET) {
            total += n;
        }
    }

    cout << total << endl;

    // Verification: known smallest values with each persistence
    assert(persistence(77) == 4);    // 77->49->36->18->8
    assert(persistence(679) == 5);   // 679->378->168->48->32->6
    assert(persistence(6788) == 6);
    assert(persistence(68889) == 7);

    return 0;
}