Enigmatic Code

Programming Enigma Puzzles

Enigma 1772: Clueless

From New Scientist #2940, 26th October 2013 [link]

Enigma 1772Above is a cross-figure to complete. However, there are no across or down clues. Instead you have to ensure that:

a) if an answer uses one of the numbered squares then that answer must be divisible by the little number in that square (for example the five-figure number in 1 down must be divisible by 1, 4 and 7; similarly the five-figure number in 7 across must be divisible by 7);

b) in your answers, only two different digits can be used throughout, one of them odd and the other even;

c) the odd digit must be written at most once in any row or column of the grid.

What are the answers to 1 across, and 7 across?

Currently the online version of this puzzle seems to be missing a title. I shall update it if it is updated on the New Scientist site, or when I get my paper copy of the magazine (probably Friday).

Enigma 1316 is also called “Clueless”.

[enigma1772]

Advertisements

6 responses to “Enigma 1772: Clueless

  1. Jim Randell 24 October 2013 at 5:11 pm

    This puzzle is fairly easy to solve with pencil and paper, but here’s a solution using the CrossFigure() class from my enigma.py module. It considers the possible odd and even digits, and then tries to solve a cross figure puzzle for each combination (only one combination has possible solutions for each answer in the gird). This Python code runs in 43ms.

    from itertools import product
    from enigma import CrossFigure, irange, printf
    
    # consider the grid:
    #
    #  A B C D E
    #  F # G # H
    #  I J # K L
    #  M # N # P
    #  Q R S T U
    
    # output a solution
    def output(g):
      (A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T, U) = g
      # output the grid
      printf("[{A} {B} {C} {D} {E}]")
      printf("[{F} # {G} # {H}]")
      printf("[{I} {J} # {K} {L}]")
      printf("[{M} # {N} # {P}]")
      printf("[{Q} {R} {S} {T} {U}]")
      # output the answers
      printf("1A = {A}{B}{C}{D}{E}, 7A = {Q}{R}{S}{T}{U}\n")
    
    # label the squares in the grid (for convenience)
    (A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T, U) = irange(0, 19)
    
    # rows and columns
    lines = (
      # rows
      (A, B, C, D, E), (F, G, H), (I, J, K, L), (M, N, P), (Q, R, S, T, U),
      # columns
      (A, F, I, M, Q), (B, J, R), (C, G, N, S), (D, K, T), (E, H, L, P, U)
    )
    
    # consider possibilities for the odd and even digits
    for (odd, even) in product('13579', '02468'):
    
      # return n-digit multiples of m, with at most two digits (one odd and
      # one even), and any odd digit can only appear once
      def generate(n, m):
        # 0 odd digits
        s = even * n
        if s[0] != '0' and int(s) % m == 0: yield s
        # 1 odd digit
        for i in irange(1, n):
          s = ''.join((odd if j == i else even) for j in irange(1, n))
          if s[0] != '0' and int(s) % m == 0: yield s
    
      # create the puzzle
      p = CrossFigure('?' * 20)
    
      # 1 across is a 5-digit multiple of 6
      p.set_answer([(A, B, C, D, E)], list(generate(5, 6)))
    
      # 4 across is a 2-digit multiple of 4
      p.set_answer([(I, J)], list(generate(2, 4)))
    
      # 5 across is a 2-digit multiple of 5
      p.set_answer([(K, L)], list(generate(2, 5)))
    
      # 7 across is a 5-digit multiple of 7
      p.set_answer([(Q, R, S, T, U)], list(generate(5, 7)))
    
      # 1 down is a 5-digit multiple of 28
      p.set_answer([(A, F, I, M, Q)], list(generate(5, 28)))
    
      # 2 down is a 2-digit multiple of 2
      p.set_answer([(C, G)], list(generate(2, 2)))
    
      # 3 down is a 5-digit multiple of 3
      p.set_answer([(E, H, L, P, U)], list(generate(5, 3)))
    
      # 6 down is a 2-digit multiple of 6
      p.set_answer([(N, S)], list(generate(2, 6)))
    
      # final check
      p.set_check(lambda g: all(sum(1 for i in line if g[i] == odd) < 2 for line in lines))
    
      # solve the puzzle
      for g in p.solve():
        output(g)
    

    Solution: The answer to 1 across is 44454. The answer to 7 across is 45444.

    Here’s the completed grid:

    Enigma 1772 - Solution

    • Jim Randell 21 November 2013 at 12:35 pm

      Here’s the manual solution:

      Both 1A and 1D must end with the even digit, hence both 3D and 7A must start with it, so it cannot be 0. So 5A must have 5 as its final digit and the even digit as its first digit.

      So 3D must be composed of four even digits with a 5 in the middle, and be divisible by 3. The only possible candidate is 44544.The rest of the grid then follows.

  2. Brian Gladman 24 October 2013 at 5:36 pm

    These ‘cross figure’ enigmas are very uninspiring in my view.

    # each '.' represents a digit position in the 5 by 5 grid
    fmt = '|.....|\n|.X.X.|\n|..X..|\n|.X.X.|\n|.....|\n'
    
    # the indexes in 'fmt' that make the numbers in the grid
    nbrs = ((1, 2, 3, 4, 5), (1, 9, 17, 25, 33), (5, 13, 21, 29, 37),
            (33, 34, 35, 36, 37), (3, 11), (17, 18), (20, 21), (27, 35))
    # the divisors of these numbers
    divs = (6, 28, 3, 7, 2, 4, 5, 6)
    
    # indexes in 'fmt' that make up the rows and columns in the grid
    rows = ((1, 2, 3, 4, 5), (9, 11, 13), (17, 18, 20, 21), (25, 27, 29), 
            (33, 34, 35, 36, 37))
    cols = ((1, 9, 17, 25, 33), (2, 18, 34), (3, 11, 27, 35), (4, 20, 36), 
            (5, 13, 21, 29, 37))
    
    # check if any complete numbers, rows or columns meet the criteria
    def it_works(g, dp):
      # form the numbers
      for i, ix in enumerate(nbrs):
        sx = ''.join(g[j] for j in ix)
        # if they are complete, check that they are divisible as required
        if '.' not in sx:
          val = int(sx)
          if not val or val % divs[i]:
            return False
      # form the rows and columns
      for ix in rows + cols:
        sx = ''.join(g[j] for j in ix)
        # check if any contain the odd number more than once
        if sx.count(dp[1]) > 1:
          return False
      return True
    
    # place a digit in the grid
    def place(g, dp):
      # output the answers(s) if the grid is complete
      if '.' not in g:
        print('Answers: {:s} and {:s}'.format(g[1:6], g[33:38]))
      else:
        # otherwise try each of the two allowed digits
        for c in dp:
          xx = g.replace('.', c, 1)
          # check that any numbers in the grid are valid
          if it_works(xx, dp):
            # continue to place numbers
            place(xx, dp)
    
    # from five across we can only have 'e5' with e even 
    # or 'o0' with o odd - tuples are (even, odd)
    digit_pairs = ( [(e, '5') for e in '02468'] +
                    [('0', x) for x in '13579'] )
    for dp in digit_pairs:
      place(fmt, dp)
    
    • Jim Randell 24 October 2013 at 5:47 pm

      Agreed – it’s not a very inspiring puzzle.

      I wrote the CrossFigure() solver because it was more fun to write the general solver than solve another cross figure puzzle (Enigma 1755), but of course that makes subsequent puzzles even less of a challenge. (Except it’s nice to know that the code I wrote does work on them).

      And I don’t think you need even to consider the ‘o0’ pairs for 5A, because both 1A and 1D must end with the even digit, so 3D and 7A must start with it, hence it can’t be 0.

      • Brian Gladman 25 October 2013 at 7:57 am

        I agree that I could cut out the digit pairs including a zero as you suggest. When I started this, I added this restriction on digit pairs as I thought that a recursion depth of 20 might make it slow even though each step only involved two alternatives. But looking at all (even, odd) diigit pairs is still almost instantaneous so it was really not necessary. ..

  3. ahmet çetinbudaklar 25 October 2013 at 10:18 am

    25,45,65 and 85 are the only numbers divisible by 5 under the limitations given.

    Then by trial and error one can reach the two digits , hence the solution.

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: