All Euler problems
Project Euler

Cube Digit Pairs

Two cubes each have 6 faces with a distinct digit (0-9) on each face. By placing the two cubes side by side, we can form two-digit square numbers: 01, 04, 09, 16, 25, 36, 49, 64, 81. The digit 6 an...

Source sync Apr 19, 2026
Problem #0090
Level Level 04
Solved By 13,263
Languages C++, Python
Answer 1217
Length 493 words
linear_algebrabrute_forcecombinatorics

Problem Statement

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

Each of the six faces on a cube has a different digit (\(0\) to \(9\)) written on it; the same is done to a second cube. By placing the two cubes side-by-side in different positions we can form a variety of \(2\)-digit numbers.

For example, the square number \(64\) could be formed:

PIC

In fact, by carefully choosing the digits on both cubes it is possible to display all of the square numbers below one-hundred: \(01\), \(04\), \(09\), \(16\), \(25\), \(36\), \(49\), \(64\), and \(81\).

For example, one way this can be achieved is by placing \(\{0, 5, 6, 7, 8, 9\}\) on one cube and \(\{1, 2, 3, 4, 8, 9\}\) on the other cube.

However, for this problem we shall allow the \(6\) or \(9\) to be turned upside-down so that an arrangement like \(\{0, 5, 6, 7, 8, 9\}\) and \(\{1, 2, 3, 4, 6, 7\}\) allows for all nine square numbers to be displayed; otherwise it would be impossible to obtain \(09\).

In determining a distinct arrangement we are interested in the digits on each cube, not the order.

  • \(\{1, 2, 3, 4, 5, 6\}\) is equivalent to \(\{3, 6, 4, 1, 2, 5\}\)

  • \(\{1, 2, 3, 4, 5, 6\}\) is distinct from \(\{1, 2, 3, 4, 5, 9\}\)

But because we are allowing \(6\) and \(9\) to be reversed, the two distinct sets in the last example both represent the extended set \(\{1, 2, 3, 4, 5, 6, 9\}\) for the purpose of forming \(2\)-digit numbers.

How many distinct arrangements of the two cubes allow for all of the square numbers to be displayed?

Problem 90: Cube Digit Pairs

Mathematical Analysis

Setup

Each cube has 6 faces chosen from digits 0-9, so each cube is a 6-element subset of {0,1,2,3,4,5,6,7,8,9}\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9\}.

There are (106)=210\binom{10}{6} = 210 possible cubes.

Required Digit Pairs

The nine two-digit squares require these pairs (first digit, second digit):

SquarePair
01(0, 1)
04(0, 4)
09(0, 9)
16(1, 6)
25(2, 5)
36(3, 6)
49(4, 9)
64(6, 4)
81(8, 1)

6/9 Interchangeability

Since 6 and 9 are interchangeable, whenever we check if a cube contains a 6 or 9, we check if it contains either 6 or 9. This effectively means that if a cube has a 6, it can also represent 9, and vice versa.

Checking a Pair of Cubes

For each required pair (a,b)(a, b), the two cubes can display it if:

  • Cube 1 has aa and Cube 2 has bb, OR
  • Cube 1 has bb and Cube 2 has aa.

(With 6/9 equivalence applied.)

Counting Arrangements

Since the two cubes are unordered (swapping them gives the same arrangement), we count pairs (C1,C2)(C_1, C_2) with C1C2C_1 \le C_2 (in some canonical ordering), or equivalently count all ordered pairs and divide by 2 for distinct cubes, adding back the cases where C1=C2C_1 = C_2.

More simply: iterate over all pairs iji \le j from the 210 possible cubes.

Total pairs to check: (2102)+210=210×2112=22155\binom{210}{2} + 210 = \frac{210 \times 211}{2} = 22155.

Editorial

Each cube is just a 6-element subset of the ten digits, so the full search space is small enough to enumerate directly. The only subtlety is the 6/96/9 symmetry: once a cube carries either of those digits, it can serve as both when displaying a square.

The implementation first generates every possible cube, then checks every unordered pair of cubes. For a pair to be valid, every required square must be displayable in at least one orientation, meaning one cube supplies the tens digit and the other cube supplies the units digit, or vice versa. The candidates are therefore all cube pairs, and the nine square-digit requirements are the filter that discards invalid arrangements.

Pseudocode

Generate every 6-digit subset of the digits 0 through 9.
Set the answer count to 0.

For each unordered pair of generated cubes:
    Assume the pair is valid

    For each required square-digit pair:
        Check whether the two cubes can display it in one order or the other,
        treating 6 and 9 as interchangeable

        If this square cannot be displayed:
            mark the cube pair invalid and stop checking this pair

    If the pair remained valid:
        increase the answer count

Return the answer count.

Correctness

Theorem. The method described above computes exactly the quantity requested in the problem statement.

Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer. \square

Complexity Analysis

  • Time: O(2102)×9=O(199,395)O\binom{210}{2} \times 9 = O(199{,}395). Trivially fast.
  • Space: O(210)O(210) for storing cubes.

Answer

1217\boxed{1217}

Code

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

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

int main() {
    // Generate all C(10,6) = 210 possible cubes
    vector<vector<int>> cubes;
    for (int mask = 0; mask < 1024; mask++) {
        if (__builtin_popcount(mask) == 6) {
            vector<int> cube;
            for (int i = 0; i < 10; i++)
                if (mask & (1 << i))
                    cube.push_back(i);
            cubes.push_back(cube);
        }
    }

    // Required pairs for squares 01,04,09,16,25,36,49,64,81
    int pairs[][2] = {
        {0,1}, {0,4}, {0,9}, {1,6}, {2,5}, {3,6}, {4,9}, {6,4}, {8,1}
    };

    auto has = [](const vector<int>& cube, int d) -> bool {
        for (int x : cube) {
            if (x == d) return true;
            // 6 and 9 are interchangeable
            if (d == 6 && x == 9) return true;
            if (d == 9 && x == 6) return true;
        }
        return false;
    };

    int count = 0;
    int n = cubes.size();

    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
            bool valid = true;
            for (auto& p : pairs) {
                int a = p[0], b = p[1];
                bool ok = (has(cubes[i], a) && has(cubes[j], b)) ||
                          (has(cubes[j], a) && has(cubes[i], b));
                if (!ok) { valid = false; break; }
            }
            if (valid) count++;
        }
    }

    cout << count << endl;
    return 0;
}