Enigmatic Code

Programming Enigma Puzzles

Enigma 1349: Alphabet magic

From New Scientist #2508, 16th July 2005

The simplest “magic square” is shown below, left. It comprises nine different numbers in a 3×3 grid, such that the three rows, the three columns and the two diagonals all have the same “magic total”, in this case 15.

Enigma 1349

We may now form a second grid by writing the names of the nine numbers in English in the corresponding squares. Finally, we can form a third grid by writing the numbers of letters in the names in the corresponding squares (above, right). This is a rather uninteresting grid of numbers.

To make it more interesting, George has created a magic square of nine different numbers, not consecutive, but all less than 50. He has then formed the corresponding grid of names, and the grid of numbers of letters. If you have found George’s “alphabetic magic” square, your third grid will contain nine different numbers forming a magic square.

What are the magic totals of George’s two magic squares?

[enigma1349]

Advertisements

One response to “Enigma 1349: Alphabet magic

  1. Jim Randell 5 February 2014 at 6:46 am

    This Python program uses the int2words() function from the enigma.py library. It runs in 35ms.

    from collections import defaultdict
    from itertools import combinations, product
    from enigma import irange, int2words, printf
    
    # find the number of letters in each number
    n2c = defaultdict(list)
    for n in irange(1, 49):
      c = sum(1 for x in int2words(n) if x.isalpha())
      n2c[c].append(n)
    
    # choose nine numbers that count letters
    for cs in combinations(n2c.keys(), 9):
      # these form the third magic square
      # so the magic number is...
      (s3, r) = divmod(sum(cs), 3)
      if r > 0: continue
      # and the central digits is...
      (e3, r) = divmod(s3, 3)
      if r > 0: continue
      # choose d and f (and let d < f)
      for d3 in cs:
        f3 = s3 - (d3 + e3)
        cs1 = set(cs).difference((d3, e3, f3))
        if len(cs1) != 6: continue
        # now choose a
        for a3 in cs1:
          g3 = s3 - (a3 + d3)
          i3 = s3 - (a3 + e3)
          h3 = s3 - (g3 + i3)
          b3 = s3 - (e3 + h3)
          c3 = s3 - (a3 + b3)
          if not(c3 + f3 + i3 == c3 + e3 + g3 == s3): continue
          if len(cs1.difference((a3, g3, i3, h3, b3, c3))) != 0: continue
          # for uniqueness let a be the smallest corner, and b < d
          if not(b3 < d3 and min(a3, c3, g3, i3) == a3): continue
    
          # now find the original square
          for (e1, d1) in product(n2c[e3], n2c[d3]):
            s1 = 3 * e1
            f1 = s1 - (e1 + d1)
            if not(f1 in n2c[f3]): continue
            for a1 in n2c[a3]:
              g1 = s1 - (a1 + d1)
              i1 = s1 - (a1 + e1)
              h1 = s1 - (g1 + i1)
              b1 = s1 - (e1 + h1)
              c1 = s1 - (a1 + b1)
              if not(c1 + f1 + i1 == c1 + e1 + g1 == s1): continue
              if not all(x1 in n2c[x3] for (x1, x3) in ((g1, g3), (i1, i3), (b1, b3), (c1, c3))): continue
    
              printf("square 1: sum={s1} [{a1} {b1} {c1} / {d1} {e1} {f1} / {g1} {h1} {i1}]")
              (a2, b2, c2, d2, e2, f2, g2, h2, i2) = (int2words(x) for x in (a1, b1, c1, d1, e1, f1, g1, h1, i1))
              printf("square 2: [{a2}, {b2}, {c2} / {d2}, {e2}, {f2} / {g2}, {h2}, {i2}]")
              printf("square 3: sum={s3} [{a3} {b3} {c3} / {d3} {e3} {f3} / {g3} {h3} {i3}]")
              printf()
    

    Solution: The magic total of the first magic square is 45. The magic total of the second magic square is 21.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: