Enigmatic Code

Programming Enigma Puzzles

Enigma 1173: Six months

From New Scientist #2329, 9th February 2002 [link]

The months MAY, JUN, JUL and AUG are indicated in the two multiplications shown where all the digits have been replaced by capital letters and asterisks. In these multiplications, and in the clues that follow, different capital letters stand for different digits but the same capital letter always stands for the same digit while the asterisks can be any digit.

 

Enigma 1173

Typically, the months JAN and MAR are both exactly divisible by 31, and of course you can also assume that any YEAR is exactly divisible by 12 or even 52.

What is the product of each multiplication?

[enigma1173]

Advertisements

3 responses to “Enigma 1173: Six months

  1. Jim Randell 4 April 2016 at 7:44 am

    This Python program runs in 37ms.

    from collections import defaultdict
    from itertools import permutations, product
    from enigma import irange, split, nconcat, divc, divf, printf
    
    # possible digits
    digits = set(irange(0, 9))
    
    # generate solutions for a multiplication sum: abc * xyz
    # where the result is 5-digits and each of the intermediate products is 3-digits
    # the final intermediate product, abc * x is given (as p)
    def multiplication(p):
      # p = abc * x
      for x in irange(1, 9):
        (abc, r) = divmod(p, x)
        if abc < 100: break
        if r > 0: continue
    
        # (abc * y) and (abc * z) are also 3-digit numbers
        for (y, z) in product(irange(divc(100, abc), divf(999, abc)), repeat=2):
          xyz = nconcat(x, y, z)
          # the result of the sum is ...
          r = abc * xyz
          if r > 99999: continue
          yield (abc, xyz, r)
    
    # find 3-digit multiples of 31 with distinct digits
    # and record them by the middle digit
    r = defaultdict(list)
    for i in irange(4, 32):
      n = i * 31
      (x, y, z) = split(n, int)
      if len(set((x, y, z))) == 3:
        r[y].append(n)
    
    # consider values of A
    for (A, vs) in r.items():
      # and corresponding values for JAN and MAR
      for (JAN, MAR) in permutations(vs, 2):
        (J, _, N) = split(JAN, int)
        (M, _, R) = split(MAR, int)
        # remaining digits
        ds1 = digits.difference([J, A, N, M, R])
        if len(ds1) != 5: continue
    
        # consider possible values for Y and E
        for (Y, E) in permutations(ds1, 2):
          if Y == 0: continue
          # YEAR is a multiple of lcm(12, 52) = 156
          YEAR = nconcat(Y, E, A, R)
          if YEAR % 156 > 0: continue
    
          # remaining digits
          ds2 = ds1.difference([E, Y])
    
          # solve the first multiplication sum
          MAY = nconcat(M, A, Y)
          for (a1, b1, r1) in multiplication(MAY):
            (J1, U, N1, _, _) = split(r1, int)
            if not(J1 == J and N1 == N and U in ds2): continue
    
            # the remaining letters are G and L (in some order)
            for (G, L) in permutations(ds2.difference([U])):
    
              # solve the second multiplication sum
              JUL = nconcat(J, U, L)
              for (a2, b2, r2) in multiplication(JUL): 
                (A1, U1, G1, _, _) = split(r2, int)
                if not(A1 == A and U1 == U and G1 == G): continue
    
                printf("{a1} x {b1} = {r1}, {a2} x {b2} = {r2} [JAN={JAN} MAR={MAR} YEAR={YEAR}, U={U} G={G} L={L}]")
    

    Solution: The result of the first multiplication sum is 35109. The result of the second multiplication sum is 45696.

    The complete multiplication sums are shown below:

    Enigma 1173 - Solution

    JAN = 341 (11×31), MAR = 248 (8×31), YEAR = 9048 (754×12, 174×52).

    • Jim Randell 12 August 2016 at 1:29 pm

      It is possible to use the generalised alphametic solver (SubstitutedExpression()) from the enigma.py library to solve this one. And it can be called directly from the command line without having to write a program.

      We could introduce 28 additional symbols for the asterisks (using the --symbols="<string>" parameter) and then use the --distinct="<string>" parameter to limit the letters actually given in the diagram to be distinct, while the the remaining additional symbols can take on any value. This would allow us to read off the values for the complete sums from the solution.

      But as we don’t care about most of their values here I have just used additional symbols (lower case letters) for the multiplicands of the sums, and then I have used expressions to ensure that the intermediate multiplications in the sums are the correct “shape”.

      Finally the --answer="<expr>" parameter is used to display the results of the sums.

      % python -m enigma SubstitutedExpression \
          --symbols="AEGJLMNRUYabcdefghijkl" --distinct="AEGJLMNRUY" \
          --answer="(abc * def, ghi * jkl)" \
          "(abc * def) // 100 = JUN" \
          "99 < abc * f < 1000" \
          "99 < abc * e < 1000" \
          "abc * d = MAY" \
          "(ghi * jkl) // 100 = AUG" \
          "99 < ghi * l < 1000" \
          "99 < ghi * k < 1000" \
          "ghi * j = JUL" \
          "JAN % 31 = 0" "MAR % 31 = 0" \
          "YEAR % 12 = 0" "YEAR % 52 = 0"
      ((abc * def) // 100 = JUN) (99 < abc * f < 1000) (99 < abc * e < 1000) (abc * d = MAY) ((ghi * jkl) // 100 = AUG) (99 < ghi * l < 1000) (99 < ghi * k < 1000) (ghi * j = JUL) (JAN % 31 = 0) (MAR % 31 = 0) (YEAR % 12 = 0) (YEAR % 52 = 0)
      ((249 * 141) // 100 = 351) (99 < 249 * 1 < 1000) (99 < 249 * 4 < 1000) (249 * 1 = 249) ((119 * 384) // 100 = 456) (99 < 119 * 4 < 1000) (99 < 119 * 8 < 1000) (119 * 3 = 357) (341 % 31 = 0) (248 % 31 = 0) (9048 % 12 = 0) (9048 % 52 = 0) / A=4 E=0 G=6 J=3 L=7 M=2 N=1 R=8 U=5 Y=9 a=2 b=4 c=9 d=1 e=4 f=1 g=1 h=1 i=9 j=3 k=8 l=4 / (35109, 45696)
      (abc * def, ghi * jkl) = (35109, 45696) [1 solution]
      

      The command runs in 178ms.

  2. Brian Gladman 5 April 2016 at 10:25 pm
    from itertools import permutations, product
    
    # generate 3 x 3 digit multiplications in which all partial
    # products (less trailing zeros) have 3 digits, one is 'pp'
    # and the result has 5 digits with the top 3 matching 'pr'
    def mult(pp, pr):
      # test the divisors of the partial product
      for b3 in range(1, 10):
        if not pp % b3:
          # for those that give a possible 3 digit multiplier
          top = pp // b3
          if top < 100:
            break
          # now check for the lower 2 digits of the other mutiplier
          r = range(99 // top + 1, 999 // top + 1)
          for b2, b1 in product(r, repeat=2):
            bot = (100 * b3 + 10 * b2 + b1)
            result = top * bot
            if result // 100 == pr:
              yield result, top, bot
    
    # the year is a 4 digit multiple of 156
    for YEAR in range(7 * 156, 10000, 156):
      Y, E, A, R = (int(x) for x in str(YEAR))
      s1 = set(range(10)).difference([Y, E, A, R])
      
      # find M such that MAR is a multiple of 31 
      for M in s1:
        MAR = 100 * M + 10 * A + R
        if not MAR % 31:
          s2 = s1.difference([M])
          
          # find J and N such that JAN is a multiple of 31
          for J in s2:
            N = -(100 * J + 10 * A) % 31
            if N != J and N in s2:
              s3 = s2.difference([J, N])
              
              # now find U values that give valid multiplications
              # for MAY and JUN
              for U in s3:
                MAY = 10 * (MAR // 10) + Y
                JUN = 100 * J + 10 * U + N
                for r1, t1, b1 in mult(MAY, JUN):
                  
                  # permute the two remaining digits for G and L
                  for G, L in permutations(s3.difference([U]), 2):
                    JUL = 10 * (JUN // 10) + L
                    AUG = 100 * A + 10 * U + G
                    
                    # and test for a JUL/AUG multiplication that is valid
                    for r2, t2, b2 in mult(JUL, AUG):
                      fs = 'The results are {} ({} x {}) and {} ({} x {}).'
                      print(fs.format(r1, t1, b1, r2, t2, b2))
    

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: