Enigmatic Code

Programming Enigma Puzzles

Enigma 1682: The monkey’s paw

From New Scientist #2849, 28th January 2011 [link]

My niece has been showing me her collection of model ANIMALS. She says that some have CLAWS, some have PAWS, though she does not like their JAWS, and the monkey, like the letter Q, has a tail.

In the box, replace the 10 letters in the four words and one letter that I have written in capitals by numbers, according to alphabetic order a=1, c=3, q=17 etc. The box represents numbers 1 to 25 in some order in a magic square, where each row, column and main diagonal have the same sum.

What numbers represent the letters making up MONKEY?

[enigma1682]

4 responses to “Enigma 1682: The monkey’s paw

  1. jimrandell 26 January 2012 at 12:41 pm

    The following Python program runs in 57ms.

    from collections import defaultdict
    from itertools import combinations, permutations
    
    # the numbers in the magic square
    numbers = set(range(1, 26))
    
    # the magic constant
    s = sum(numbers) // 5
    
    # the magic square itself
    square = [0] * 25
    
    # the filled out squares
    for c in list("ACIJLMNPQSW"):
      n = ord(c) - 65
      square[n] = n+1
    
    # remove the numbers that are already filled out
    numbers.difference_update(square)
    
    # magic lines
    lines = (
      # rows
      ( 0,  1,  2,  3,  4),
      ( 5,  6,  7,  8,  9),
      (10, 11, 12, 13, 14),
      (15, 16, 17, 18, 19),
      (20, 21, 22, 23, 24),
      # columns
      ( 0,  5, 10, 15, 20),
      ( 1,  6, 11, 16, 21),
      ( 2,  7, 12, 17, 22),
      ( 3,  8, 13, 18, 23),
      ( 4,  9, 14, 19, 24),
      # diagonals
      ( 0,  6, 12, 18, 24),
      ( 4,  8, 12, 16, 20),
    )
    
    # find an incomplete line
    def incomplete(square):
      r = defaultdict(list)
      for line in lines:
        (t, m) = (0, [])
        for i in line:
          n = square[i]
          if n: t += n
          else: m.append(i)
        if m: r[len(m)].append((s - t, m))
      return r[min(r.keys())][0]
    
    # check for consistency
    def check(square):
      for line in lines:
        ns = tuple(square[i] for i in line)
        if ns.count(0) == 0:
          if sum(ns) != s: return False
      return True
    
    # output the magic square (and MONKEY)
    def output(square):
      for w in ("ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "MONKEY"):
        for i in list(w):
          print("{i}={l:2d}".format(i=i, l=square[ord(i) - 65]), end=' ')
        print('')
      print('')
    
    # solve the square
    def solve(square, numbers):
      if not numbers:
        output(square)
        return
    
      # find n numbers to fill in the gap
      (g, m) = incomplete(square)
      n = len(m)
      for t in combinations(numbers, n):
        if sum(t) != g: continue
        for p in permutations(t, n):
          # set up a new square with the line completed
          sq = list(square)
          for (i, j) in zip(m, p):
            sq[i] = j
          # check for consistency
          if check(sq):
            # try to solve it
            solve(sq, numbers.difference(p))
    
    solve(square, numbers)

    Solution: m=13, o=6, n=14, k=20, e=22, y=25.

    • Jim Randell 24 March 2012 at 10:11 am

      I’ve introduced a generic Magic Square solver into the enigma.py module, so now this program can be written:

      from enigma import MagicSquare
      
      # create a 5x5 magic square
      p = MagicSquare(5)
      
      # set the filled out squares
      for c in list("ACIJLMNPQSW"):
        i = ord(c) - 65
        p.set(i, i + 1)
      
      # solve the square
      if p.solve():
        # output the square and the solution
        for w in ("ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "MONKEY"):
          for i in list(w):
            print("[{i}={l:2d}]".format(i=i, l=p.square[ord(i) - 65]), end=' ')
          print('')
      
  2. Hugh Casement 16 May 2016 at 7:53 am

    Another associative magic square: opposite pairs sum to 26, two fifths of the magic constant.

  3. geoffrounce 8 February 2018 at 7:17 pm
    % A Solution in MiniZinc
    include "globals.mzn";
    
    var 1..25:  a;  var 1..25: b;  var 1..25: c;   var 1..25: d;   var 1..25: e;
    var 1..25:  f;   var 1..25: g;  var 1..25: h;   var 1..25:  i;   var 1..25:  j;
    var 1..25:  k;  var 1..25: l;    var 1..25: m;  var 1..25: n;   var 1..25: o;
    var 1..25:  p;  var 1..25: q;  var 1..25: r;    var 1..25: s;   var 1..25: t;
    var 1..25:  u;  var 1..25: v;   var 1..25: w;  var 1..25: x;   var 1..25: y;
    
    constraint all_different ( [
    a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y
    ] );
    
    constraint  a = 1 /\ c = 3 /\ i = 9 /\ j = 10 /\ l =12 /\ m = 13 /\ n  = 14 
    /\ p = 16 /\ q  = 17 /\ s  = 19 /\ w  = 23;
    
    % each row, column and main diagonals to have the same sum
    constraint all_equal ([ 
    % horizontal sums
    a + b + c + d + e,  f + g + h + i + j,  k + l + m + n + o,  p + q + r + s + t,  u + v + w + x + y,
    % vertical sums
    a + f + k + p + u,  b + g + l + q  + v,  c + h + m + r + w,  d + i + n+ s + x,  e + j + o + t + y,
    % diagonal sums
    a + g + m + s + y,  e + i + m + q + u
    ] ) ;
    
    solve satisfy;
    
    output [ "m, o, n, k, e, y  =  " ++ show(m) ++ ",  " ++ show(o) ++ ",  " ++  show(n) ++ ",  "  
    ++ show(k) ++ ",  " ++ show(e) ++ ",  " ++ show(y) ];
    
    % m, o, n, k, e, y  =  13,  6,  14,  20,  22,  25
        
    % Grid
    % a = 1; b = 21; c = 3; d = 18; e = 22;
    % f = 24; g = 7; h = 15; i = 9; j = 10;
    % k = 20; l = 12; m = 13; n = 14; o = 6;
    % p = 16; q = 17; r = 11; s = 19; t = 2;
    % u = 4; v = 8; w = 23; x = 5; y = 25;
    % ----------
    % Finished in 98msec
    
    
    

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

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

%d bloggers like this: