All Euler problems
Project Euler

Numbers for which Euler's Totient Function Equals 13!

Find the 150,000 -th number n (in ascending order) for which varphi(n) = 13! = 6,227,020,800.

Source sync Apr 19, 2026
Problem #0248
Level Level 12
Solved By 1,538
Languages C++, Python
Answer 23507044290
Length 332 words
number_theorymodular_arithmeticrecursion

Problem Statement

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

The first number \(n\) for which \(\phi (n)=13!\) is \(6227180929\).

Find the \(150\,000\)<sup>th</sup> such number.

Problem 248: Numbers for which Euler’s Totient Function Equals 13!

Mathematical Foundation

Theorem 1 (Totient product formula). For n=i=1kpiain = \prod_{i=1}^{k} p_i^{a_i} with distinct primes pip_i,

φ(n)=i=1kpiai1(pi1).\varphi(n) = \prod_{i=1}^{k} p_i^{a_i - 1}(p_i - 1).

Proof. This is standard: among the pap^a multiples of 1 up to pap^a, exactly pa1p^{a-1} are divisible by pp, so φ(pa)=papa1=pa1(p1)\varphi(p^a) = p^a - p^{a-1} = p^{a-1}(p-1). Multiplicativity of φ\varphi for coprime arguments completes the proof. \square

Lemma 1 (Candidate prime criterion). If panp^a \mid n with pp prime and a1a \ge 1, then pa1(p1)φ(n)=13!p^{a-1}(p-1) \mid \varphi(n) = 13!. In particular, (p1)13!(p-1) \mid 13!.

Proof. From Theorem 1, pa1(p1)p^{a-1}(p-1) is one factor in the product for φ(n)\varphi(n), hence divides φ(n)=13!\varphi(n) = 13!. \square

Theorem 2 (Candidate prime enumeration). The set of primes pp that can divide any nn with φ(n)=13!\varphi(n) = 13! is

P={p prime:(p1)13!}.\mathcal{P} = \{p \text{ prime} : (p-1) \mid 13!\}.

Since 13!=21035527111313! = 2^{10} \cdot 3^5 \cdot 5^2 \cdot 7 \cdot 11 \cdot 13, the divisors of 13!13! that are one less than a prime determine P\mathcal{P}. There are exactly 459 such primes.

Proof. By Lemma 1, any prime dividing nn must satisfy (p1)13!(p-1) \mid 13!. Conversely, for each divisor dd of 13!13!, if d+1d + 1 is prime, it is a candidate. Exhaustive enumeration of the τ(13!)=1163222=1584\tau(13!) = 11 \cdot 6 \cdot 3 \cdot 2 \cdot 2 \cdot 2 = 1584 divisors of 13!13! and primality testing yields 459 primes. \square

Theorem 3 (Recursive construction). All solutions nn to φ(n)=T\varphi(n) = T (with T=13!T = 13!) can be enumerated by the following recursive procedure. Choose primes p1p2p_1 \le p_2 \le \cdots from P\mathcal{P} and exponents ai1a_i \ge 1, building n=piain = \prod p_i^{a_i} while maintaining the residual target T=T/piai1(pi1)T' = T / \prod p_i^{a_i - 1}(p_i - 1). The recursion terminates when T=1T' = 1 (valid solution) or T<1T' < 1 (prune).

Proof. Every nn with φ(n)=T\varphi(n) = T has a unique prime factorisation. By processing primes in non-decreasing order, each factorisation is visited exactly once. The residual target tracks the remaining totient to be achieved, and each chosen prime-power pap^a contributes pa1(p1)p^{a-1}(p-1) to the totient. The recursion explores all valid combinations exhaustively. \square

Lemma 2 (Exponent bound). For prime pp with residual target TT', the maximum exponent aa satisfies pa1(p1)Tp^{a-1}(p-1) \le T', i.e., a1+logp(T/(p1))a \le 1 + \lfloor \log_p(T'/(p-1)) \rfloor.

Proof. The contribution pa1(p1)p^{a-1}(p-1) must divide TT', hence not exceed it. \square

Editorial

We find candidate primes. Finally, recursive enumeration. We perform a recursive search over the admissible choices, prune branches that violate the derived constraints, and keep only the candidates that satisfy the final condition.

Pseudocode

Find candidate primes
Recursive enumeration
Sort and return 150000th

Complexity Analysis

  • Time: The recursion tree has branching factor bounded by P=459|\mathcal{P}| = 459 at each level, but the residual target shrinks multiplicatively, limiting depth to O(logT/log2)33O(\log T / \log 2) \approx 33. Empirically, about 548,000548{,}000 solutions are found, with search time dominated by the enumeration. Sorting: O(NlogN)O(N \log N) with N548,000N \approx 548{,}000.
  • Space: O(N)O(N) to store all solutions, plus O(logT)O(\log T) recursion stack depth.

Answer

23507044290\boxed{23507044290}

Code

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

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

int main() {
    // Find the 150000th number n for which phi(n) = 13!
    long long target = 6227020800LL; // 13!

    // Factorization of 13! = 2^10 * 3^5 * 5^2 * 7 * 11 * 13
    vector<pair<long long, int>> factors = {{2,10},{3,5},{5,2},{7,1},{11,1},{13,1}};

    // Generate all divisors
    vector<long long> divisors;
    divisors.push_back(1);
    for (auto& [p, e] : factors) {
        int sz = divisors.size();
        long long pk = 1;
        for (int k = 1; k <= e; k++) {
            pk *= p;
            for (int i = 0; i < sz; i++) {
                divisors.push_back(divisors[i] * pk);
            }
        }
    }
    sort(divisors.begin(), divisors.end());

    auto isPrime = [](long long n) -> bool {
        if (n < 2) return false;
        if (n < 4) return true;
        if (n % 2 == 0 || n % 3 == 0) return false;
        for (long long i = 5; i * i <= n; i += 6) {
            if (n % i == 0 || n % (i + 2) == 0) return false;
        }
        return true;
    };

    // Candidate primes
    vector<long long> primes;
    for (long long d : divisors) {
        if (isPrime(d + 1)) {
            primes.push_back(d + 1);
        }
    }
    sort(primes.begin(), primes.end());
    primes.erase(unique(primes.begin(), primes.end()), primes.end());

    // Recursively find all n such that phi(n) = target
    // n = p1^a1 * p2^a2 * ... where p1 < p2 < ...
    // phi(n) = prod(pi^(ai-1) * (pi-1))

    vector<long long> solutions;

    function<void(int, long long, long long)> search = [&](int idx, long long rem, long long n) {
        if (rem == 1) {
            // n and 2*n both have the same totient if n is odd
            // But p=2 with k=1 contributes factor 1 to phi, so 2*n is handled
            // when we include p=2 with k=1.
            solutions.push_back(n);
            return;
        }
        for (int i = idx; i < (int)primes.size(); i++) {
            long long p = primes[i];
            if (p - 1 > rem) break;
            if (rem % (p - 1) != 0) continue;
            long long r = rem / (p - 1);
            long long pk = 1; // p^(k-1), n_factor = p^k
            long long n_factor = p;
            while (true) {
                if (r % pk != 0) break;
                // Check overflow: n * n_factor
                if (n_factor > 1e18 / n) break; // overflow protection
                search(i + 1, r / pk, n * n_factor);
                pk *= p;
                n_factor *= p;
            }
        }
    };

    search(0, target, 1);

    sort(solutions.begin(), solutions.end());

    // 150000th (1-indexed)
    if ((int)solutions.size() >= 150000) {
        cout << solutions[150000 - 1] << endl;
    } else {
        cout << "Not enough solutions: " << solutions.size() << endl;
    }

    return 0;
}