# Enigmatic Code

Programming Enigma Puzzles

## Enigma 106: Magic box

From New Scientist #1250, 23rd April 1981 [link]

Many interesting number patterns can be made with popular 15-puzzle in which the numbers from 1 to 15 can slide around in a four-by-four framework.

For example, it is possible to make the top left-hand three-by-three block into many different Magic Squares (i.e. each row of three, each column of three and each diagonal of three adds to the same sum). One such arrangement is shown.

It is also possible to do this in such a way that, again with the space in the bottom right-hand corner, the three numbers in the bottom row of the frame add up to the same total as the three numbers in the right-hand column of the frame, which also add up to the same total as the four numbers in the diagonal of the frame from the bottom left to the top right-hand corner. (And, incidentally, this total is more than each of the row sums of the Magic Square).

Give, in increasing order, the four numbers which must form that diagonal of this special arrangement.

[enigma106]

### 2 responses to “Enigma 106: Magic box”

1. Jim Randell 9 July 2013 at 8:36 am

This Python solution uses the properties of the 15-puzzle (explored in Enigma 1444), and the properties of the 3×3 magic square (explored in Enigma 1680). It runs in 41ms.

```# consider the square:
#
# a b c u
# d e f v
# g h i w
# x y z
#
# a b c / d e f / g h i form a 3x3 magic square

from enigma import irange, T, divc, printf

# check for possible arrangements of the 15-puzzle
def check(*s):
# count the inversions
n = sum(sum(1 for x in s[i+1:] if v > x) for (i, v) in enumerate(s))
# the count should be even
if n % 2: return
# what is the diagonal?
d = sorted((s[3], s[6], s[9], s[12]))
# print the solution
printf("diagonal={d} [{s}]", s=' '.join(str(x) for x in s))

# the tiles and their sum
tiles = set(irange(1, 15))
t = sum(tiles)

# the smallest 3x3 magic square sum is T(9)/3
mn = divc(T(9), 3)
# and max is 3x + 2(x + 1) = 5x + 2 = t
mx = (t - 2) // 5

# consider the magic sum
for s in irange(mn, mx):
# magic sums must be multiples of 3 (see Enigma 1680)
(e, r) = divmod(s, 3)
if r > 0: continue
# compute the required secondary sum
(s2, r) = divmod(t - 3 * s, 2)
if r > 0: continue

printf("[s={s} s2={s2}]")

# find possible magic squares with sum s
for a in tiles.difference([e]):
i = s - (a + e)
if i not in tiles: continue
for b in tiles.difference([a, e, i]):
c = s - (a + b)
g = s - (c + e)
d = s - (a + g)
f = s - (c + i)
h = s - (b + e)
# remaining tiles
rs = tiles.difference([a, b, c, d, e, f, g, h, i])
if len(rs) != 6: continue
# find suitable p, q, r and x, y, z that sum to s2
for p in rs:
x = s2 - (p + f + h)
if x not in rs: continue
for q in rs.difference([p, x]):
r = s2 - (p + q)
yz = sorted(rs.difference([p, q, r, x]))
if len(yz) != 2: continue
for (y, z) in (yz, yz[::-1]):
check(a, b, c, p, d, e, f, q, g, h, i, r, x, y, z)
```

Solution: The numbers in the diagonal are 1, 8, 9 and 15.

The program produces the 8-different arrangements of the puzzle that give a solution to the puzzle.

You can verify that the solutions given can actually be made with a standard 15-puzzle by using the Python sliding puzzle solver I wrote for Enigma 1444 (see [ http://jimpulse.blogspot.co.uk/2013/04/sliding-puzzle-in-python.html ]), using commands like this:

% python sliding-puzzle.py 4 4 5 3 10 8 11 6 1 12 2 9 7 13 15 14 4

2. Hugh Casement 16 July 2015 at 1:53 pm

The top left magic square reads

``` 5  3 10
11  6  1
2  9  7```

The other corners (u and x) have 8 and 15 or vice versa.
The row or column containing 8 is completed with 12 and 13 in either order;
the row or column containing 15 is completed with 14 and 4 in either order,
but if one pair is swapped then the other must be too, to preserve parity.
I had to try that out with real sliders, not having understood how to do it by program.

Reflexions in the leading diagonal are also possible, of course.
That gives us the eight possible arrangements (eight further being unattainable).

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