# Enigmatic Code

Programming Enigma Puzzles

## Enigma 469: Enigmatic dominoes

From New Scientist #1620, 7th July 1988 [link]

I have an ordinary set of 28 dominoes, but I’ve painted over the numbers. I’ve left the blanks alone and painted E’s over the 1’s, N’s over the 2’s, I’s over the 3’s, G’s over the 4’s, M’s over the 5’s and A’s over the 6’s.

My nephew was playing with the dominoes and managed to arrange 18 of them, some “horizontal” and some “vertical”, so that the letters and blanks were in the positions shown.

I forgot which letters were in the positions marked “?” but I remember that all four “?”s were the same, and no two were on the same domino.

Which letter is “?” and how many of the 18 dominoes were “horizontal”.

[enigma469]

### One response to “Enigma 469: Enigmatic dominoes”

1. Jim Randell 8 October 2018 at 8:02 am

This Python 3 program runs in 130ms.

Run: [ @repl.it ]

```from enigma import ordered, diff, partition, irange, printf

# assign numbers to the symbols (7 for unknown)
(E, N, I, G, M, A, _, U, X) = (1, 2, 3, 4, 5, 6, 0, 7, None)

grid = [
X, X, X, X, X, X, X, X, X, X, X, X, X, X,
X, A, N, _, _, _, E, N, I, G, M, A, _, X,
X, _, E, N, I, G, M, A, _, U, U, U, U, X,
X, G, A, M, E, _, _, E, N, I, G, M, A, X,
X, X, X, X, X, X, X, X, X, X, X, X, X, X,
]

# unallocated squares in the grid
unallocated = list(i for (i, v) in enumerate(grid) if v != X)

# place dominoes until all squares are allocated
# ds - dominoes placed
# ps - positions (i, j, k), k = 1 for horizontal
def solve(unallocated, ds=[], ps=[]):
if not unallocated:
yield (ds, ps)
else:
i = unallocated[0]
s = list()
if i + 1 in unallocated:
# attempt to place a horizontal domino at (i, i+1)
s.append((i, i + 1, 1))
if i + 14 in unallocated:
# attempt to place a vertical domino at (i, i+14)
s.append((i, i + 14, 0))
for (i, j, k) in s:
# determine the domino at (i, j)
d = ordered(grid[i], grid[j])
# dominoes can't be repeated
if d in ds: continue
# solve for the remaining dominoes
yield from solve(diff(unallocated, (i, j)), ds + [d], ps + [(i, j, k)])

# replace u with v in tuple t
def replace(t, u, v):
return tuple(v if x == u else x for x in t)

# find "unknown" value from a set of dominoes
def unknown(ds):
# separate the dominoes in to knowns, unknowns
(unknowns, knowns) = partition((lambda d: U in d), ds)
# consider possible unknown values
for n in irange(0, 6):
# replacement dominoes
rs = set(ordered(*(replace(d, U, n))) for d in unknowns)
if len(rs) != len(unknowns): continue
if rs.intersection(knowns): continue
yield (n, rs.union(knowns))

# solve the grid
for (ds, ps) in solve(unallocated):
# can't have 2 unknowns on the same domino
if (U, U) in ds: continue
# allocate the unknown number
for (n, rs) in unknown(ds):
# output solution
h = sum(k for (i, j, k) in ps)
printf("? = {n}, horizontal = {h}", n="_ENIGMA"[n])
# output dominoes and positions
for (d, (i, j, k)) in zip(ds, ps):
(a, b) = ordered(*(replace(d, U, n)))
printf("  {a}-{b} @ {i},{j} {k}", k='VH'[k])
printf(
```

Solution: The squares marked with “?” should be “I”. There are 6 horizontal dominoes.

There is only one layout that satisfies all the conditions:

Without the condition that there can’t be two “unknowns” on the same domino there is a further solution with 8 horizontal dominoes.

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