Enigmatic Code

Programming Enigma Puzzles

Enigma 1624: French magic numbers

From New Scientist #2789, 4th December 2010 [link]

In a magic square the sums of each row, column and major diagonal are equal. There is a remarkable relationship between the two magic squares shown here. Each integer in the one on the left when written as a word in English contains the number of letters indicated by the corresponding integer in the one on the right: “twenty-five” has 10 letters, “eight” has five letters, and so on.

I wondered whether I could create a new magic square on the left such that every integer in it when written as a word in French contains the number of letters indicated by the corresponding integer in the square that we already have on the right. It isn’t possible to do this, but I have created a new square in which seven of the integers fulfil this requirement and the other two are each just one letter short of the number of letters required.

As in the English example, all the integers in my new square are considerably less than 100.

What is my new square?

[enigma1624]

One response to “Enigma 1624: French magic numbers”

1. jimrandell 14 December 2011 at 9:50 pm

The following Python program runs in 48ms.

```from collections import defaultdict
from enigma import is_distinct, printf

# map french numbers to a count of the letters
#      0   1   2   3   4   5   6   7   8   9
f = [  4,  2,  4,  5,  6,  4,  3,  4,  4,  4, # 0x
3,  4,  5,  6,  8,  6,  5,  7,  7,  7, # 1x
5,  9,  9, 10, 11,  9,  8,  9,  9,  9, # 2x
6, 10, 10, 11, 12, 10,  9, 10, 10, 10, # 3x
8, 12, 12, 13, 14, 12, 11, 12, 12, 12, # 4x
9, 13, 13, 14, 15, 13, 12, 13, 13, 13, # 5x
8, 12, 12, 13, 14, 12, 11, 12, 12, 12, # 6x
11, 14, 13, 14, 16, 14, 13, 15, 15, 15, # 7x
12, 13, 15, 16, 17, 15, 14, 15, 15, 15, # 8x
14, 15, 16, 17, 19, 17, 16, 18, 18, 18, # 9x
]

n = defaultdict(list)
for i in range(1, 100):
n[f[i]].append(i)

for a1 in n[9] + n[10]:
a2 = f[a1]
for b1 in n[4] + n[5]:
if not is_distinct(a1, b1): continue
b2 = f[b1]
for c1 in n[5] + n[6]:
if not is_distinct(c1, a1, b1): continue
c2 = f[c1]
s1 = a1 + b1 + c1
for d1 in n[2] + n[3]:
if not is_distinct(d1, a1, b1, c1): continue
d2 = f[d1]

e1 = (a1 + d1) - c1
if not(0 < e1 < 100): continue
if not is_distinct(e1, a1, b1, c1, d1): continue
if not(e1 in n[6] or e1 in n[7]): continue
e2 = f[e1]

f1 = s1 - (d1 + e1)
if not(0 < f1 < 100): continue
if not is_distinct(f1, a1, b1, c1, d1, e1): continue
if not(f1 in n[10] or f1 in n[11]): continue
f2 = f[f1]

g1 = s1 - (a1 + d1)
if not(0 < g1 < 100): continue
if not is_distinct(g1, a1, b1, c1, d1, e1, f1): continue
if not(g1 in n[7] or g1 in n[8]): continue
g2 = f[g1]

h1 = s1 - (b1 + e1)
if not(0 < h1 < 100): continue
if not is_distinct(h1, a1, b1, c1, d1, e1, f1, g1): continue
if not(h1 in n[8] or h1 in n[9]): continue
h2 = f[h1]

i1 = s1 - (c1 + f1)
if not(0 < i1 < 100): continue
if not is_distinct(i1, a1, b1, c1, d1, e1, f1, g1, h1): continue
if not(i1 in n[3] or i1 in n[4]): continue
i2 = f[i1]

if not(s1 == g1 + h1 + i1 == a1 + e1 + i1): continue

# only two numbers are allowed to be off by one
if (a2 - 9) + (b2 - 4) + (c2 - 5) + (d2 - 2) + (e2 - 6) + (f2 - 10) + (g2 - 7) + (h2 - 8) + (i2 - 3) != 7: continue

printf("{s1} {s2}", s1=(a1, b1, c1, d1, e1, f1, g1, h1, i1), s2=(a2, b2, c2, d2, e2, f2, g2, h2, i2))
```

Solution: The magic square is:

```23 12 16 10 17 24 18 22 11```