All Euler problems
Project Euler

Cubic Permutations

The cube 41063625 = 345^3 can be obtained by permuting the digits of 56623104 = 384^3. Find the smallest cube for which exactly five permutations of its digits are also cubes.

Source sync Apr 19, 2026
Problem #0062
Level Level 02
Solved By 35,849
Languages C++, Python
Answer 127035954683
Length 483 words
combinatoricsalgebrabrute_force

Problem Statement

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

The cube, \(41063625\) (\(345^3\)), can be permuted to produce two other cubes: \(56623104\) (\(384^3\)) and \(66430125\) (\(405^3\)). In fact, \(41063625\) is the smallest cube which has exactly three permutations of its digits which are also cube.

Find the smallest cube for which exactly five permutations of its digits are cube.

Problem 62: Cubic Permutations

Mathematical Foundation

Definition 1. For a positive integer mm, define the canonical digit signature σ(m)\sigma(m) as the string obtained by sorting the decimal digits of mm in non-decreasing order. For example, σ(41063625)=01234566\sigma(41063625) = 01234566.

Theorem 1 (Permutation equivalence). Two positive integers aa and bb are digit permutations of each other if and only if σ(a)=σ(b)\sigma(a) = \sigma(b).

Proof. (\Rightarrow) If bb is a digit permutation of aa, there exists a bijection π\pi on digit positions such that the ii-th digit of aa equals the π(i)\pi(i)-th digit of bb. Hence aa and bb share the same multiset of digits, and sorting both multisets yields the same string.

(\Leftarrow) If σ(a)=σ(b)\sigma(a) = \sigma(b), the multisets of digits coincide. Since any two sequences with the same multiset are permutations of each other, bb is a digit permutation of aa. \square

Lemma 1 (Digit count preservation). If m3m^3 and n3n^3 are digit permutations of each other (with m,n1m, n \ge 1), then m3m^3 and n3n^3 have the same number of digits.

Proof. Two numbers sharing the same digit multiset necessarily have the same total digit count, since neither has a leading zero (both being positive cubes 1\ge 1). \square

Theorem 2 (Digit-count finality). Let D(k)=log10k+1D(k) = \lfloor \log_{10} k \rfloor + 1 denote the number of decimal digits of k>0k > 0. For a fixed digit count dd, define the equivalence classes

Cd={[c]:c=n3 with D(n3)=d}\mathcal{C}_d = \bigl\{ [c] : c = n^3 \text{ with } D(n^3) = d \bigr\}

where [c]={m3:σ(m3)=σ(c),  D(m3)=d}[c] = \{m^3 : \sigma(m^3) = \sigma(c),\; D(m^3) = d\}. Then no cube with a different digit count can belong to any class in Cd\mathcal{C}_d. Consequently, once all cubes with dd digits have been enumerated, the class sizes within Cd\mathcal{C}_d are final.

Proof. By Lemma 1, any cube that is a digit permutation of a dd-digit cube must itself have dd digits. Therefore, dd'-digit cubes with ddd' \ne d cannot enter any class in Cd\mathcal{C}_d. When all nn with D(n3)=dD(n^3) = d have been processed, no future cube can modify the classes. \square

Lemma 2 (Range of dd-digit cubes). The cubes with exactly dd digits are {n3:nId}\{n^3 : n \in I_d\} where Id=[10(d1)/3,(10d1)1/3]I_d = [\lceil 10^{(d-1)/3} \rceil, \lfloor (10^d - 1)^{1/3} \rfloor]. In particular, Id=Θ(10d/3)|I_d| = \Theta(10^{d/3}).

Proof. The condition 10d1n310d110^{d-1} \le n^3 \le 10^d - 1 is equivalent to 10(d1)/3n(10d1)1/310^{(d-1)/3} \le n \le (10^d - 1)^{1/3}. The interval length is (10d1)1/310(d1)/3=Θ(10d/3)(10^d - 1)^{1/3} - 10^{(d-1)/3} = \Theta(10^{d/3}). \square

Corollary. The algorithm can process cubes in order of nn and finalize all classes of digit count dd as soon as the first (d+1)(d+1)-digit cube is encountered.

Editorial

We generate cubes in increasing order and group them by their canonical digit signatures, but only within a fixed digit length. This digit-length partition is important because once the number of digits increases, no later cube can belong to any group from the previous layer. At each such transition we inspect the completed groups from the previous digit length, and if one of them contains exactly five cubes, the smallest cube in that group is the answer. Otherwise we discard the old groups and continue with the next digit length.

Pseudocode

Initialize the grouping structure for the current digit length.
Start with no active digit length.

For each positive integer n:
    compute the cube c = n^3
    determine the number of digits of c

    if this is the first cube of a new digit length:
        inspect every group from the previous digit length
        if one of them contains exactly five cubes, return its smallest element
        reset the grouping structure for the new digit length

    place c into the group indexed by its sorted digit signature

Complexity Analysis

Time: Let KK be the value of nn at termination. For each nn, we compute n3n^3 in O(1)O(1) (or O(d)O(d) for arbitrary-precision integers), sort its dd digits in O(dlogd)O(d \log d), and perform a hash-map lookup in O(d)O(d) expected time. The answer occurs at n=5027n = 5027 with d=12d = 12 digits, giving total cost O(Kdlogd)O(5027×12×4)=O(2.4×105)O(K \cdot d \log d) \approx O(5027 \times 12 \times 4) = O(2.4 \times 10^5).

Space: O(Id)O(|I_d|) for the groups hash map within the current digit count, since completed digit counts are discarded.

Answer

127035954683\boxed{127035954683}

Code

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

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

int main() {
    map<string, vector<long long>> groups;
    int prev_digits = 0;
    long long answer = 0;

    for (long long n = 1; ; n++) {
        long long cube = n * n * n;
        string s = to_string(cube);
        int d = s.size();

        if (d > prev_digits && prev_digits > 0) {
            // Finalize all groups of the previous digit count
            for (auto& [key, vec] : groups) {
                if ((int)key.size() == prev_digits && vec.size() == 5) {
                    if (answer == 0 || vec[0] < answer)
                        answer = vec[0];
                }
            }
            if (answer) {
                cout << answer << endl;
                return 0;
            }
            prev_digits = d;
        }
        if (prev_digits == 0) prev_digits = d;

        string key = s;
        sort(key.begin(), key.end());
        groups[key].push_back(cube);
    }
}