# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1069: Time for elevenses

From New Scientist #2225, 12th February 2000 [link]

I have a cube. On each of its faces is a digit, the style of writing being rather like the display on a calculator. I hold the cube to look at one of its faces from the front and then, keeping the upper and lower faces horizontal, I swivel the cube around and note the digits which I see (all seemingly the right way up) and hence I read off a four-figure number which is divisible by eleven.

Now I repeat the process starting this time looking from the front at one of the faces which was horizontal in the previous manoeuvre. Once again I read off a four-figure number which is divisible by eleven.

Now I start again with the cube in exactly the same position as it was at the start of the first process. This time I keep the left-hand and right-hand faces vertical and I swivel the cube around. Once again I read a four-figure number which is divisible by eleven and also by three odd integers less than eleven.

What was that last four figure number?

[enigma1069]

### One response to “Enigma 1069: Time for elevenses”

1. Jim Randell 26 March 2018 at 7:39 am

There are many possibilities for the exact sequence of moves used in the puzzle, this code tries them all, and finds several solutions, but the third number (and the first number) are the same in all instances. There are two layouts of the cube which mirror each other.

This Python code runs in 765ms.

Run: [ @repl.it ]

```from collections import defaultdict
from itertools import product
from enigma import irange, icount, nsplit, update, printf

X = None

# map digits (0-9) to patterns (0, 1, 2, 3, 4, 5, 6, 7, 8) and orientation
digits = {
#   0- 1- 2- 3- quarter turns
0: (0, 0, 0, 0),
1: (1, X, 1, X),
2: (2, X, 2, X),
3: (3, X, X, X),
4: (4, X, X, X),
5: (5, X, 5, X),
6: (6, X, 9, X), # pattern for 9 is the same as pattern for 6
7: (7, X, X, X),
8: (8, X, 8, X),
}

# map each <digit> to a (<pattern>, <rotation>)
pattern = dict()
for (p, ds) in digits.items():
for (r, d) in enumerate(ds):
if d is None or d in pattern: continue
pattern[d] = (p, r)

# a cube is a sequence of (<pattern>, <rotation>) pairs for faces F, B, U, D, L, R
(F, B, U, D, L, R) = (0, 1, 2, 3, 4, 5)

# the empty cube
cube0 = [None] * 6

# available moves on the cube
_moves = {
'F': ((F, 1), (B, 3), (L, 1), (R, 1), (D, 1), (U, 1)),
'B': ((F, 3), (B, 1), (R, 3), (L, 3), (U, 3), (D, 3)), # B = FFF
'U': ((R, 0), (L, 2), (U, 1), (D, 3), (F, 0), (B, 2)),
'D': ((L, 0), (R, 2), (U, 3), (D, 1), (B, 2), (F, 0)), # D = UUU
'L': ((U, 0), (D, 0), (B, 0), (F, 0), (L, 1), (R, 3)),
'R': ((D, 0), (U, 0), (F, 0), (B, 0), (L, 3), (R, 1)), # R = LLL
}

# make a move on the cube
def move(cube, m):
c = list()
for (f, r) in _moves[m]:
if cube[f] is None:
x = None
else:
(p, q) = cube[f]
x = (p, (q + r) % 4)
c.append(x)
return c

# apply a sequence of moves to a cube
# * = read a digit from the front face
def moves(seq, cube):
ds = list()
for m in seq:
if m == "*":
# * = read the front face as a digit
if cube[F] is None:
ds.append(None)
else:
(p, q) = cube[F]
d = digits[p][q]
if d is None: return
ds.append(d)
else:
# apply the move
cube = move(cube, m)
# retun the rotated cube, and any digits read off
return (cube, ds)

# find the cube that matches a given sequence of moves against digits ds
def match(seq, ds, cube):
ds = list(ds)
for m in seq:
if m == '*':
# * = match the front face to the next digit
d = ds.pop(0)
if cube[F] is None:
# if F is unassigned place the required pattern there
cube = update(cube, [F], [pattern[d]])
else:
# check the pattern matches the next digit
(p, q) = cube[F]
if digits[p][q] != d: return
else:
# apply the move
cube = move(cube, m)
return cube

# we read the third number with one of the following sequences:
#
#  (*L*L*L*, *R*R*R*) [2]
#
# we read the first number with one of:
#
#  (*D*D*D*, *U*U*U*) [2]
#
# and the second number with one of:
#
#  (L, R) + ("", "F", "FF", "FFF") + (*D*D*D*, *U*U*U*) [2.4.2 = 16]
#
# so 2.2.16 = 64 possible sequences altogether

# 4-digit multiples of 11
m11s = list(irange(1001, 9999, step=11))

# accumulate results by n3
ans = defaultdict(int)

# consider possible values for the third number
# which must be a multiple of 11
for n3 in m11s:
# and also a multiple of exactly 3 of 1, 3, 5, 7, 9
if icount((3, 5, 7, 9), (lambda d: n3 % d == 0), 3) != 2: continue

# consider possible sequences that give this number
# and return the cube to the original orientation
for seq3 in ["*L*L*L*L", "*R*R*R*R"]:
# find a cube that matches
cube3 = match(seq3, nsplit(n3, 4), cube0)
if cube3 is None: continue

# now consider possible values for the first number
# which must be a multiple of 11
for n1 in m11s:

# consider possible sequences that will give this number
# and return the cube to the original orientation
for seq1 in ["*D*D*D*D", "*U*U*U*U"]:
# find a cube that matches
cube1 = match(seq1, nsplit(n1, 4), cube3)
if cube1 is None: continue

# consider possible starting positions and sequences for the second number
for (s1, s2, s3) in product(["L", "R"], ["", "F", "FF", "FFF"], ["*D*D*D*", "*U*U*U*"]):
seq2 = s1 + s2 + s3

# read the digits from the cube
r = moves(seq2, cube1)
if r is None: continue
(_, ds) = r

# check the digits read off match a multiple of 11
for n2 in m11s:
if all(a is None or a == b for (a, b) in zip(ds, nsplit(n2, 4))):
ans[n3] += 1
# output a solution
printf("[n1={n1} n2={n2} n3={n3}, cube={cube1}, seq1={seq1} seq2={seq2} seq3={seq3}]", seq1=seq1[:-1], seq3=seq3[:-1])

# output accumulated results
for (n3, v) in ans.items():
printf("n3 = {n3} [{v} solutions]")
```

Solution: The third four digit number is 9625.

9625 is a multiple of 1, 5, 7, and 11.

The first number is 9020, and the second number is 5060 or 6050 (depending on the exact sequence of moves used, and the layout of the cube).

The cube has a “6/9” pattern on the front (initially reading as a 9) and “2” pattern on the back. The up and down face have a “6/9” and “5” pattern on. And the left and right faces both have a “0” pattern on.

The puzzle relies on the fact that the “0” pattern can be interpreted as a 0 digit in any quarter-turn orientation (not just upright and upside-down) – the puzzle says the digits are “rather like” 7-segment digits on a calculator, so we can suppose they are somewhat squarer. If you modify the declaration for the pattern “0” at line 10 to only represent 0 in 0- and 2- quarter turns you will find there are no solutions.

Reading the first and third numbers provide enough information to fully describe all faces of the cube.

This site uses Akismet to reduce spam. Learn how your comment data is processed.