Enigmatic Code

Programming Enigma Puzzles

Enigma 1144: Isaac Newton (?-1727)

From New Scientist #2300, 21st July 2001 [link]

Enigma 1144

Isaac Newton, 1642-1727? or 1643-1727? The discrepancy of course is due to the overlap of the Julian and Gregorian calendars and to avoid any controversy I have omitted his birth year altogether in the given multiplications, leaving only 1727 as shown. All other digits have been replaced by letters and asterisks.

However, the mechanistic laws of motion attributed to this great scientists provide another clue and this is given by the simple equation: F = m × A.

In the multiplications and the clue, different capital letters stand for different digits and the same capital letter stands for the same digit. Asterisks and the lower-case letter, m, can be any digit.

What is the value of SCIENTIST?

[enigma1144]

Advertisements

2 responses to “Enigma 1144: Isaac Newton (?-1727)

  1. Jim Randell 24 October 2016 at 8:27 am

    We can use the general Alphametic solver (SubstitutedExpression()) from the enigma.py library to solve this puzzle without having to write a program. We introduce additional (lower-case) symbols for the multiplicands of the sum using the --symbols=<string> parameter (so the first sum is abc × def and the second sum is ghi × kl7), and we allow these to take on any value, by using the --distinct=<string> parameter to select only the upper-case letters.

    We then construct expressions for the intermediate products. In the first sum, we are only interested in the fact that each has exactly three digits. In the second sum the expressions are a little more complicated.

    We use the --answer=<expr> parameter to select the required answer.

    Here is the command and its (quite verbose) output. It runs in 147ms.

    % python -m enigma SubstitutedExpression \
        --symbols="ACEFINOSTWabcdefghiklm" --distinct="ACEFINOSTW" \
        --answer="SCIENTIST" \
        "abc * def = ISAAC" \
        "99 < abc * f < 1000" \
        "99 < abc * e < 1000" \
        "99 < abc * d < 1000" \
        "ghi * (10 * kl + 7) = NEWTON" \
        "999 < ghi * 7 < 10000" "((ghi * 7) // 10) % 10 = 2" \
        "99 < ghi * l < 1000" "((ghi * l) // 10) % 10 = 7" \
        "999 < ghi * k < 10000" "((ghi * k) // 10) % 10 = 1" \
        "m * A = F"
    (abc * def = ISAAC) (99 < abc * f < 1000) (99 < abc * e < 1000) (99 < abc * d < 1000) (ghi * (10 * kl + 7) = NEWTON) (999 < ghi * 7 < 10000) (((ghi * 7) // 10) % 10 = 2) (99 < ghi * l < 1000) (((ghi * l) // 10) % 10 = 7) (999 < ghi * k < 10000) (((ghi * k) // 10) % 10 = 1) (m * A = F)
    (215 * 323 = 69445) (99 < 215 * 3 < 1000) (99 < 215 * 2 < 1000) (99 < 215 * 3 < 1000) (389 * (10 * 82 + 7) = 321703) (999 < 389 * 7 < 10000) (((389 * 7) // 10) % 10 = 2) (99 < 389 * 2 < 1000) (((389 * 2) // 10) % 10 = 7) (999 < 389 * 8 < 10000) (((389 * 8) // 10) % 10 = 1) (2 * 4 = 8) / A=4 C=5 E=2 F=8 I=6 N=3 O=0 S=9 T=7 W=1 a=2 b=1 c=5 d=3 e=2 f=3 g=3 h=8 i=9 k=8 l=2 m=2 / 956237697
    SCIENTIST = 956237697 [1 solution]
    

    Solution: SCIENTIST = 956237697.

    (And NEW = 321).

    The full multiplication sums are:

    enigma-1144-solution

    And the solution for F = m × A is 8 = 2 × 4.

    To make things easier you can put all the command line arguments to enigma.py into a file (with “shell-like” syntax) and then use the -r / --run command-line argument to execute the solver.

    For example if the following is saved to a file called enigma1144.run

    # use the alphametic solver
    SubstitutedExpression
    
    # solver parameters
    --symbols="ACEFINOSTWabcdefghiklm"
    --distinct="ACEFINOSTW"
    --answer="SCIENTIST"
    
    # expressions to solve
    "abc * def = ISAAC"
    "99 < abc * f < 1000"
    "99 < abc * e < 1000"
    "99 < abc * d < 1000"
    "ghi * (10 * kl + 7) = NEWTON"
    "999 < ghi * 7 < 10000" "((ghi * 7) // 10) % 10 = 2"
    "99 < ghi * l < 1000" "((ghi * l) // 10) % 10 = 7"
    "999 < ghi * k < 10000" "((ghi * k) // 10) % 10 = 1"
    "m * A = F"
    

    Then we can just run the command: python -m enigma -r enigma1144.run, as follows:

    % python -m enigma -r enigma1144.run
    (abc * def = ISAAC) (99 < abc * f < 1000) (99 < abc * e < 1000) (99 < abc * d < 1000) (ghi * (10 * kl + 7) = NEWTON) (999 < ghi * 7 < 10000) (((ghi * 7) // 10) % 10 = 2) (99 < ghi * l < 1000) (((ghi * l) // 10) % 10 = 7) (999 < ghi * k < 10000) (((ghi * k) // 10) % 10 = 1) (m * A = F)
    (215 * 323 = 69445) (99 < 215 * 3 < 1000) (99 < 215 * 2 < 1000) (99 < 215 * 3 < 1000) (389 * (10 * 82 + 7) = 321703) (999 < 389 * 7 < 10000) (((389 * 7) // 10) % 10 = 2) (99 < 389 * 2 < 1000) (((389 * 2) // 10) % 10 = 7) (999 < 389 * 8 < 10000) (((389 * 8) // 10) % 10 = 1) (2 * 4 = 8) / A=4 C=5 E=2 F=8 I=6 N=3 O=0 S=9 T=7 W=1 a=2 b=1 c=5 d=3 e=2 f=3 g=3 h=8 i=9 k=8 l=2 m=2 / 956237697
    SCIENTIST = 956237697 [1 solution]
    

    (I know this works on Unix-like systems such as Linux and Mac OS X (or macOS as we are supposed to call it now). I’d be interested in reports from other systems).

    In fact on a Unix-like system, you can put the command in the first line of the file (preceded by the special characters #!), and execute the file directly (by making it executable).

    So we would add the following line at the top of enigma1144.run

    #!/usr/bin/env python -m enigma -r
    

    Make sure the file is executable (using: % chmod a+x enigma1144.run), and then we can run it directly from the shell:

    % ./enigma1144.run
    (abc * def = ISAAC) (99 < abc * f < 1000) (99 < abc * e < 1000) (99 < abc * d < 1000) (ghi * (10 * kl + 7) = NEWTON) (999 < ghi * 7 < 10000) (((ghi * 7) // 10) % 10 = 2) (99 < ghi * l < 1000) (((ghi * l) // 10) % 10 = 7) (999 < ghi * k < 10000) (((ghi * k) // 10) % 10 = 1) (m * A = F)
    (215 * 323 = 69445) (99 < 215 * 3 < 1000) (99 < 215 * 2 < 1000) (99 < 215 * 3 < 1000) (389 * (10 * 82 + 7) = 321703) (999 < 389 * 7 < 10000) (((389 * 7) // 10) % 10 = 2) (99 < 389 * 2 < 1000) (((389 * 2) // 10) % 10 = 7) (999 < 389 * 8 < 10000) (((389 * 8) // 10) % 10 = 1) (2 * 4 = 8) / A=4 C=5 E=2 F=8 I=6 N=3 O=0 S=9 T=7 W=1 a=2 b=1 c=5 d=3 e=2 f=3 g=3 h=8 i=9 k=8 l=2 m=2 / 956237697
    SCIENTIST = 956237697 [1 solution]
    
  2. Brian Gladman 25 October 2016 at 9:14 pm

    I thought that this was going to be quite slow but it isn’t because the individual products are stll heavily constrained even when considered independently (where the right hand product has only a single solution).

    from itertools import product
    from functools import reduce
    
    # compile the set of solutions for the left hand product
    # ensuring that all partial products have three digits
    sol_l = set()
    for top in range(100, 1000):
      for b0 in range(1, 10):
        pp0 = b0 * top    
        if not 100 <= pp0 < 1000:
          continue
    
        for b1 in range(1, 10):
          pp1 = b1 * top
          if not 100 <= pp1 < 1000:
            continue
        
          for b2 in range(1, 10):
            pp2 = b2 * top
            if not 100 <= pp2 < 1000:
              continue
          
            # ensure that ISAAC has the correct form and, since
            # F = m * A < 10 for some m > 1, that 0 < A < 5 
            isaac = 100 * pp2 + 10 * pp1 + pp0
            if not isaac >= 100000:
              i, s, a, _a, c = li = [int(x) for x in str(isaac)]
              if 0 < a < 5 and _a == a and len(set(li)) == 4:
                sol_l.add((top, 100 * b2 + 10 * b1 + b0, frozenset(li), a))
    
    # compile the set of solutions for the right hand product
    # ensuring that the partial products have the given forms
    sol_r = set()
    for top in range(100, 1000):
      pp0 = 7 * top
      if pp0 < 1000 or (pp0 % 100) // 10 != 2:
        continue
    
      for b1 in range(1, 10):
        pp1 = b1 * top
        if not 100 <= pp1 < 1000 or (pp1 % 100) // 10 != 7:
          continue
        
        for b2 in range(1, 10):
          pp2 = b2 * top
          if pp2 < 1000 or (pp2 % 100) // 10 != 1:
            continue
          
          # ensure that NEWTON has the correct form
          newton = 100 * pp2 + 10 * pp1 + pp0
          n, e, w, t, o, _n = li = [int(x) for x in str(newton)]
          if _n == n and len(set(li)) == 5:
            sol_r.add((top, 100 * b2 + 10 * b1 + 7, frozenset(li)))
            
    # now consider all possible pairs of solutions for the two products
    for (tl, bl, sl, a), (tr, br, sr) in product(sol_l, sol_r):
      
      # they must not share any digits as they don't share any letters
      if not sl & sr:
        # find F and check that F = m * A for some m > 1
        f, = set(range(10)).difference(sl | sr)
        m, r = divmod(f, a)
        if m > 1 and not r:
          
          # form a map from letters to digits
          li = [int(x) for x in str(tl * bl) + str(tr * br)]
          d = dict(zip('ISA_CNEWTO_', li))
          # and use it to compose SCIENTIST      
          sc = reduce(lambda x, y: 10 * x + y, [d[c] for c in 'SCIENTIST'])
          fs = '{} x {} = {}, {} x {} = {}, SCIENTIST = {}.'
          print(fs.format(tl, bl, tl * bl, tr, br, tr * br, sc))
    

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: