Cube digit pairs
Each of the six faces on a cube has a different digit ( to ) 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 -digit numbers.
For example, the square number could be formed:

In fact, by carefully choosing the digits on both cubes it is possible to display all of the square numbers below one-hundred: , , , , , , , , and .
For example, one way this can be achieved is by placing on one cube and on the other cube.
However, for this problem we shall allow the or to be turned upside-down so that an arrangement like and allows for all nine square numbers to be displayed; otherwise it would be impossible to obtain .
In determining a distinct arrangement we are interested in the digits on each cube, not the order.
- is equivalent to
- is distinct from
But because we are allowing and to be reversed, the two distinct sets in the last example both represent the extended set for the purpose of forming -digit numbers.
How many distinct arrangements of the two cubes allow for all of the square numbers to be displayed?
Implementations
#include <iostream>#include <vector>
bool has_digit(int mask, int d) { if (mask & (1 << d)) return true; if (d == 6 && (mask & (1 << 9))) return true; if (d == 9 && (mask & (1 << 6))) return true; return false;}
bool can_form_square(int mask_a, int mask_b, int sq) { int d1 = sq / 10, d2 = sq % 10; bool a1 = has_digit(mask_a, d1), a2 = has_digit(mask_a, d2); bool b1 = has_digit(mask_b, d1), b2 = has_digit(mask_b, d2); return (a1 && b2) || (a2 && b1);}
long long cube_digit_pairs() { std::vector<int> squares = {1, 4, 9, 16, 25, 36, 49, 64, 81}; std::vector<int> cubes; for (int i = 0; i < (1 << 10); ++i) { if (__builtin_popcount(i) == 6) { cubes.push_back(i); } } long long count = 0; int n = cubes.size(); for (int i = 0; i < n; ++i) { int ma = cubes[i]; for (int j = i + 1; j < n; ++j) { int mb = cubes[j]; bool ok = true; for (int sq : squares) { if (!can_form_square(ma, mb, sq)) { ok = false; break; } } if (ok) ++count; } } return count;}Solution Notes
Mathematical Background
This problem involves finding pairs of cubes with digits 0-9 that can form all two-digit square numbers (01 through 81) by arranging the cubes side by side. The cubes have 6 faces each, and digits 6 and 9 are considered interchangeable since they can be rotated.
Algorithm Analysis
The solution generates all possible combinations of 6 digits from 10 (C(10,6) = 210) for each cube using bitmasks or combinations. It then checks all unordered pairs to see if they can form each required square by ensuring the digits are available on either cube in the correct positions.
Performance
All implementations run efficiently in under 100ms, with the combinatorial approach being fast due to the small number of combinations.
Key Insights
- Bitmasks provide efficient digit checking and storage.
- Handling 6/9 interchangeability is crucial for covering squares like 09 and 90.
- The problem requires checking both possible arrangements for each square digit pair.
Educational Value
Demonstrates combinatorial enumeration and bit manipulation techniques, with a practical application to puzzle-solving and constraint satisfaction.
Problem #90 is taken from Project Euler and licensed under CC BY-NC-SA 4.0.