Enigmatic Code

Programming Enigma Puzzles

Enigma 1282: Amen

From New Scientist #2440, 27th March 2004

Janet was trying to invent one of those puzzles where every letter stands for a different digit (0 to 9).

She looked at the sum of the two-figure numbers SO + BE = IT and found that there were several possible answers, such as 21 + 37 = 58. John studied the puzzle and also found several answers, such as 5 × 0 + 3 × 6 = 2 × 9. But he had misunderstood and had treated the expression as being algebraic. When they compared answers they discovered there were a few sets of the 6 letter-values which they agreed about.

Which digits do not appear in any of their common answers?

Note: I am still waiting for a phone line to be connected at my new house, so I only have sporadic access to the internet at the moment. The current estimate is that I should have a connection in early November.

[enigma1282]

7 responses to “Enigma 1282: Amen

  1. Jim Randell 31 October 2014 at 4:55 pm

    This Python program uses the [[ SubstitutedSum() ]] solver from the enigma.py library. It runs in 54ms, about twice as fast as using [[ itertools.permutations() ]].

    from enigma import irange, SubstitutedSum, printf
    
    digits = set(irange(0, 9))
    
    p = SubstitutedSum(['SO', 'BE'], 'IT')
    
    # solve the standard substituted sum
    for s in p.solve():
      # check the algebraic sum
      (S, O, B, E, I, T) = (s[x] for x in 'SOBEIT')
      if S * O + B * E != I * T: continue
      printf("[S={S} O={O}, B={B} E={E}, I={I} T={T}]")
      # remove the used digits
      digits.difference_update(s.values())
    
    printf("remaining digits = {digits}")
    

    Solution: The digits 0 and 4 do not appear in any of the common solutions.

    The terms SO and BE are interchangeable, so there are essentially three different solutions.

    19 + 37 = 56; 1×9 + 3×7 = 5×6.
    29 + 38 = 67; 2×9 + 3×8 = 6×7.
    39 + 18 = 57; 3×9 + 1×8 = 5×7.

    • geoffrounce 31 October 2014 at 8:22 pm
      digits = set('1234567890')
      from itertools import permutations
      
      for p in permutations('1234567890',6):
        s,o,b,e,i,t = p
        if all (x != '0' for x in (s,o,b,e,i,t)):
          if (int(s)* int(o)) + (int(b)* int(e)) == int(i)* int(t): 
            so, be, it = int(s + o), int(b + e), int(i + t)
            if so + be == it:
              print('Common sum : ', so, '+', be,'=', it)
              digits.difference_update((s,o,b,e,i,t))
              
      print('Unused digits =',digits)
      
      # Common sum :  18 + 39 = 57
      # Common sum :  19 + 37 = 56
      # Common sum :  29 + 38 = 67
      # Common sum :  37 + 19 = 56
      # Common sum :  38 + 29 = 67
      # Common sum :  39 + 18 = 57
      # Unused digits = {'0', '4'}
      
      • arthurvause 1 November 2014 at 8:37 am

        Hi Geoff, I was wondering about the restriction that all s,o,b,e,i,t are non-zero.
        s,b,i have to be non-zero to make two figure numbers, but I can’t see why o,e,t necessarily have to be non-zero.

        • geoffrounce 1 November 2014 at 9:59 am

          Hi Arthur, you are right, but result not affected. Your solution is neat.
          Any reason not to use Python 3 ?

          • arthurvause 1 November 2014 at 11:06 am

            I started using 2.7 a few years ago as I wanted to use bitarray for some prime number sieves. I think it was only available for 2.7 at the time, and I have never got round to upgrading. The other factor is that if I write code in 2.7, it works on Python 2 and 3 (with a few minor exceptions)

  2. arthurvause 31 October 2014 at 11:22 pm

    The set of options can be reduced by noting that either:
    t=o+e ; i=s+b
    t=o+e-10 ; i=s+b+1
    depending on whether there is a carry in the non-algebraic interpretation.

    from itertools import permutations
    
    nonappearance = set(range(10))
    
    for s,b,o,e in permutations(range(10),4):
      if 0 not in (s,b):
        for carry in (0,1):
          t = o+e - 10*carry
          i = s+b+carry
    
          if i and len(set((s,o,b,e,i,t)))==6 \
             and s*o+b*e == i*t:
            nonappearance -=set((s,o,b,e,i,t))
    
    print "digits not appearing are ", list(nonappearance)      
    
  3. arthurvause 1 November 2014 at 9:49 am

    The number of options can be reduced even further:

    from itertools import permutations
    
    nonappearance = set(range(10))
    
    #assume w.l.o.g. s < b
    for s in xrange(1,5):
      for b in xrange(s+1,10-s):
        for o,e in permutations(set(range(10))-set((s,b)),2):
          i,t = divmod(10*(s+b)+o+e,10)
          if i <= 9 and len(set((s,o,b,e,i,t)))==6 \
             and s*o+b*e == i*t:
            nonappearance -=set((s,o,b,e,i,t))
    
    print "digits not appearing are ", list(nonappearance)      
    

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: