Enigmatic Code

Programming Enigma Puzzles

Enigma 1448: Birthday magic

From New Scientist #2609, 23rd June 2007

For my brother-in-law’s birthday in 2007 I made up a 4-by-4 magic square for him. Each of the rows, columns and main diagonals added up to his new age. I told him this but then only gave him the incomplete version shown below.

He managed to complete the square but only then realized that the top row of the square represented his date of birth, in the form:

What is his date of birth?

[enigma1448]

2 responses to “Enigma 1448: Birthday magic”

1. Jim Randell 23 March 2013 at 9:42 am

I turned the puzzle in a set of simultaneous equations, and then used the SymPy library to solve it using Python. It runs in 310ms.

```# consider the square as:
# [ a] [ b] [19] [ c]
# [39] [ d] [ 1] [ 6]
# [ 5] [ 2] [ e] [ f]
# [ g] [ h] [ i] [ 2]
# and let the magic sum (and age in 2007) = x

from sympy import symbols, Eq, solve
from enigma import printf

(a, b, c, d, e, f, g, h, i, x) = symbols(list('abcdefghix'))

eqs = (
# magic lines
Eq(x,  a +  b + 19 +  c),
Eq(x, 39 +  d +  1 +  6),
Eq(x,  5 +  2 +  e +  f),
Eq(x,  g +  h +  i +  2),
Eq(x,  a + 39 +  5 +  g),
Eq(x,  b +  d +  2 +  h),
Eq(x, 19 +  1 +  e +  i),
Eq(x,  c +  6 +  f +  2),
Eq(x,  a +  d +  e +  2),
Eq(x,  c +  1 +  2 +  g),
# also x is the current age
Eq(x, 107 - c),
)

for r in solve(eqs, dict=True):
printf("[{r}]")
printf("date of birth = {a} / {b} / {c}", a=r[a], b=r[b], c=1900 + r[c])
```

Solution: The date of birth is 1 / 3 / 1942 (i.e. 1st March 1942, his age is 65).

• Jim Randell 23 March 2013 at 12:16 pm

And here it is without using SymPy. This code runs in 41ms.

```# consider the square as:
# [ a] [ b] [19] [ c]
# [39] [ d] [ 1] [ 6]
# [ 5] [ 2] [ e] [ f]
# [ g] [ h] [ i] [ 2]
# and let the magic sum (and age in 2007) = x

from enigma import irange, printf

# a, b, c form the birthdate
for b in irange(1, 12):
for a in irange(1, 31):
# but the magic sum is x = a + b + 19 + c
# which is also his age in 2007, so x = 107 - c
(c, r) = divmod(88 - (a + b), 2)
if r > 0: continue
x = 107 - c
# compute g (two different ways)
g = x - (a + 39 + 5)
if x != c + 1 + 2 + g: continue
# and the rest
d = x - (39 + 1 + 6)
h = x - (b + d + 2)
e = x - (a + d + 2)
f = x - (5 + 2 + e)
i = x - (g + h + 2)
if x != 19 + 1 + e + i: continue
if x != c + 6 + f + 2: continue

printf("dob = {a}/{b}/{y} [x={x} a={a} b={b} c={c} d={d} e={e} f={f} g={g} h={h} i={i}]", y=1900 + c)
```