Enigmatic Code

Programming Enigma Puzzles

Enigma 102: AN )ENIGMA

Enigma 102: AN )ENIGMA

From New Scientist #1246, 26th March 1981 [link]

Here is a letters-for-digits puzzle showing that long division is often an enigma. As usual different letters consistently stand for different digits throughout.

Enigma 102

What (in letters) is the answer to this division sum?

[enigma102]

Advertisements

3 responses to “Enigma 102: AN )ENIGMA

  1. Jim Randell 25 June 2013 at 8:58 am

    Oh, goody, another long division puzzle. I took sledgehammer to this one by examining all possible 6-digit values for ENIGMA. This Python program runs in 351ms.

    #         D a b c d
    #     -------------
    # A N ) E N I G M A
    #       e G
    #       ---
    #         f I
    #         g h
    #         -----
    #         i j G
    #         A A C
    #         -----
    #           k R M
    #           l R E
    #           -----
    #             m A
    #             m A
    #             ===
    
    from itertools import permutations
    from enigma import irange, nconcat, split, printf
    
    digits = set(irange(0, 9))
    
    # ENIGMA is 6 different digits
    for (E, N, I, G, M, A) in permutations(digits, 6):
      if E == 0: continue
      ENIGMA = nconcat(E, N, I, G, M, A)
      AN = nconcat(A, N)
      (Dabcd, r) = divmod(ENIGMA, AN)
      if not(r == 0 and 9999 < Dabcd < 100000): continue
      (D, a, b, c, d) = split(Dabcd, int)
      if D in (E, N, I, G, M, A): continue
      # AN * D = eG
      (e, G1) = divmod(AN * D, 10)
      if not(G1 == G and 0 < e < 10): continue
      # AN * a = gh
      gh = AN * a
      if not(9 < gh < 100): continue
      # AN * b = AAC
      (AA, C) = divmod(AN * b, 10)
      if not(AA == A * 11 and C not in (E, N, I, G, M, A, D)): continue
      # AN * c = lRE
      (l, RE) = divmod(AN * c, 100)
      if not(0 < l < 9): continue
      (R, E1) = divmod(RE, 10)
      if not(E1 == E and R not in (E, N, I, G, M, A, D, C)): continue
      # AN * d = mA
      (m, A1) = divmod(AN * d, 10)
      if not(0 < m < 10 and A1 == A): continue
      # EN - eG = f
      f = 10 * (E - e) + (N - G)
      if not(0 < f < 10): continue
      # fI - gh = ij
      ij = 10 * f + I - gh
      if not (9 < ij < 100): continue
      # ijG - AAC = kR
      (k, R1) = divmod(10 * (ij - AA) + (G - C), 10)
      if not(0 < k < 9 and R1 == R): continue
      # kRM - lRE = m
      if 100 * (k - l) + (M - E) != m: continue
    
      # map digits to letters
      d2l = dict(zip((E, N, I, G, M, A, D, C, R), 'ENIGMADCR'))
      answer = ''.join(d2l.get(x, '?') for x in (D, a, b, c, d))
    
      printf("{Dabcd}={answer} [E={E} N={N} I={I} G={G} M={M} A={A} D={D} C={C} R={R}] [a={a} b={b} c={c} d={d} e={e} f={f} gh={gh} ij={ij} k={k} l={l} m={m}]")
    

    Solution: The answer to the sum is DANCE (= 21793).

  2. Jim Randell 13 July 2014 at 10:50 am

    Here’s a shorter solution using the SubstitutedDivision() solver from the enigma.py library. It runs in 68ms.

    from enigma import SubstitutedDivision, join, printf
    
    p = SubstitutedDivision(
      'ENIGMA', 'AN', 'D????',
      [('EN', '?G', '?'), ('?I', '??', '??'), ('??G', 'AAC', '?R'), ('?RM', '?RE', '?'), ('?A', '?A', '')]
    )
    
    for s in p.solve():
      p.output_solution(s)
      # display the result as letters
      d = dict((str(v), k) for (k, v) in s.d.items())
      r = join(d.get(x, '?') for x in str(s.c))
      printf("{s.c} = {r}")
    
    • Jim Randell 16 July 2017 at 9:49 am

      The program given above will still work with the new SubstitutedDivision() solver (although the solution will be output twice, as there is no need to call output_solution() explicitly with the new solver), but this is how I would write this program now, using the new solver:

      from enigma import SubstitutedDivision, join, printf
      
      p = SubstitutedDivision(
        "ENIGMA / AN = D????",
        ["EN - ?G = ?", "?I - ?? = ??", "??G - AAC = ?R", "?RM - ?RE = ?", "?A - ?A = 0"]
      )
      
      for s in p.solve():
        # display the result of the division as letters
        d = dict((str(v), k) for (k, v) in s.d.items())
        printf("{s.c} = {r}", r=join(d.get(x, '?') for x in str(s.c)))
      

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: