Enigmatic Code

Programming Enigma Puzzles

Enigma 8: Anti-magic square

From New Scientist #1150, 12th April 1979 [link]

Frances was trying to remember how to arrange the numbers 1 to 9 in a magic square. This was her first shot. As you see, so far from getting the 3 columns, the 3 rows and the 2 main diagonals totalling the same, she got them all different. “Look!” she said, “I have invented an anti-magic square!”

What I ask you to do is to concoct the smallest possible 3 x 3 anti-magic square with 9 whole numbers, all positive but not necessarily all different. In judging the smallest possible, the first criterion is to minimise the highest number used: the second is to minimise the total of all 9 numbers.

[enigma8]

Advertisements

4 responses to “Enigma 8: Anti-magic square

  1. Jim Randell 6 December 2011 at 10:30 am

    This Python code isn’t the fastest program (runtime is 1.1s), but it constructs the minimal solutions.

    from itertools import count
    from enigma import irange, printf
    
    def decompose(n, p, m):
      "decompose(n, m): decompose <n> into <p> numbers less than <m>"
      if n < 1: return []
      if p == 1: return [] if m < n else [[n]]
      d = []
      for i in irange(1, min(m, n)):
        for j in decompose(n-i, p-1, m):
          d.append([i] + j)
      return d
    
    def sums(a, b, c, d, e, f, g, h, i):
      "sums(s): the sums of the square"
      return (a+b+c, d+e+f, g+h+i, a+d+g, b+e+h, c+f+i, a+e+i, c+e+g)
    
    def solve():
      # for increasing max numbers (m)...
      for m in count(1):
        # and increasing totals (t)...
        for t in irange(9, 9 * m):
          done = False
          # decompose t-m into 8 numbers (not more than m)...
          for s in decompose(t - m, 8, m):
            # and stir in the max number...
            for i in irange(8, 0, step=-1):
              s.insert(i, m)
              # are the magic sums distinct?
              if len(set(sums(*s))) == 8:
                print(m, t, s)
                done = (m, t)
              s.pop(i)
          # did we find a valid (m, t) pair?
          if done:
            printf("max = {m}, total = {t}")
            return 
    
    solve()
    

    Solution: There are many squares with a highest number of a 5, and a total of 19.

  2. K 28 March 2015 at 2:25 pm

    {1,1,1},{2,2,1},{1,3,5} has sum 17.

    • Jim Randell 28 March 2015 at 3:08 pm

      1, 1, 1 / 2, 2, 1, / 1, 3, 5 doesn’t satisfy the conditions that all the rows, columns and diagonals should all have different sums. The first column is 1 + 2 + 1 = 4, and the reverse diagonal (from bottom left to top right) is also 1 + 2 + 1 = 4.

  3. K 28 March 2015 at 5:03 pm

    Reverse diagonal… OK – thanks!

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: