# Enigmatic Code

Programming Enigma Puzzles

## Enigma 857: Four cubes

From New Scientist #2012, 13th January 1996 [link]

Harry, Tom and I were challenged to find four perfect cubes, one consisting of one digit, one of two digits, one of three digits and one of four digits, such that the ten digits used included nine different digits. We were allowed to regard 0 as a valid solution for the one-digit cube.

Our solutions were all different. You might say that we each found two solutions, though each of us simply found an alternative for one of our numbers, the other three numbers being common to both solutions. The three numbers common to both my solutions did not appear in any of Harry’s or Tom’s solutions.

Please list those three numbers in ascending order.

[enigma857]

### 3 responses to “Enigma 857: Four cubes”

1. Jim Randell 24 June 2022 at 10:26 am

This Python program runs in 61m. (Internal runtime is 2.2ms).

Run: [ @replit ]

```from collections import defaultdict
from enigma import (
irange, inf, cb, ndigits, cproduct, union, nsplit,
subsets, intersect, diff, chain, printf
)

# find 1-4 digit cubes
d = defaultdict(list)
for i in irange(0, inf):
n = cb(i)
k = ndigits(n)
if k > 4: break
d[k].append(n)

# find solution sets that use 9 different digits
ss = list(ss
for ss in cproduct(d[k] for k in irange(1, 4))
if len(union(nsplit(x) for x in ss)) == 9
)

# find pairs of solution sets that share 3 numbers
rs = list(rs for rs in subsets(ss, size=2) if len(intersect(rs)) == 3)

# choose a pair for D
for D in rs:
ds = intersect(D)
# choose pairs for H and T
for (H, T) in subsets(diff(rs, {D}), size=2):
# H and T do not have any numbers in common with ds
if any(ds.intersection(x) for x in chain(H, T)): continue
# output solution
printf("ans={ds}\n-> D={D}\n-> H/T={H} / {T}", ds=sorted(ds))
```

Solution: The numbers were: 64, 729 5832.

The setters numbers were: (0|1, 64, 729 5832).

Harry and Tom’s numbers were: (0|1, 27 343 6859), (8, 27, 125|512, 4096).

There are only 6 sets of cubes that use 9 different digits, and these combine to form 3 pairs, where each pair has 3 numbers in common. And these 3 pairs are the pairs found by T, D, H.

2. GeoffR 24 June 2022 at 11:41 am

A part programme/part manual solution.
I chose to find the 6 sets of cubes for Tom, Dick and Harry and then manually annotate the multiple outputs to show that the conditions of the teaser had been met.

```% A Solution in MiniZinc
include "globals.mzn";

var 0..9:A; var 0..9:B; var 0..9:C; var 0..9:D;
var 0..9:E; var 0..9:F; var 0..9:G; var 0..9:H;
var 0..9:I; var 0..9:J;

constraint B > 0 /\ D > 0 /\ G > 0;

% The ten digits used included nine different digits
constraint card( {A, B, C, D, E, F, G, H, I, J} ) == 9;

% Cubes are (A, BC, DEF, GHIJ)
var 10..99: BC = 10*B + C;
var 100..999: DEF = 100*D + 10*E + F;
var 1000..9999: GHIJ = 1000*G + 100*H + 10*I + J;

% Sets of cubes for 1, 2, 3 and 4 digit numbers
set of int: cb1 == {0, 1, 8};
set of int: cb2 = {n * n * n | n in 3..4};
set of int: cb3 = {n * n * n | n in 5..9};
set of int: cb4 = {n * n * n | n in 10..21};

constraint A in cb1 /\ BC in cb2 /\ DEF in cb3 /\ GHIJ in cb4;

solve satisfy;

output [ "Cubes are " ++ show(A) ++ ", " ++ show(BC) ++ ", "
++ show(DEF) ++ ", " ++ show(GHIJ) ];

% Cubes are 0, 27, 343, 6859  Harry/Tom (1)
% ----------
% Cubes are 8, 27, 125, 4096  Harry/Tom (3)
% ----------
% Cubes are 8, 27, 512, 4096  Harry/Tom (4)
% ----------
% Cubes are 1, 27, 343, 6859  Harry/Tom (2)
% ----------
% Cubes are 0, 64, 729, 5832  Dick(1)
% ----------
% Cubes are 1, 64, 729, 5832  Dick(2)
% ----------
% ==========
% Dick's three numbers in ascending order are 64, 729, 5832.

```
3. Frits 30 June 2022 at 2:29 pm

Following GeoffR’s approach.

```
from enigma import SubstitutedExpression, is_cube_p

# the alphametic puzzle
p = SubstitutedExpression(
[
"is_cube_p(A)",
"is_cube_p(BC)",
"is_cube_p(DEF)",
"is_cube_p(GHIJ)",
# put A at the back so we don't miss a possible zero
"nd(BCDEFGHIJA) == 9",
],
# allow zero for A
d2i={0: "BDG"},
# number of different digits
code="nd = lambda n: len(set(x for x in str(n)))",
distinct="",
verbose=0,    # use 256 to see the generated code
)

# collect solutions
sols = [y for _, y in p.solve()]

save = set()
# find pairs of solution sets that share 3 numbers
for s1 in sols:
for s2 in sols:
common = tuple(set(s1) & set(s2))
if len(common) == 3: