Tagged: by: Danny Roth Toggle Comment Threads | Keyboard Shortcuts

  • Jim Randell 10:54 am on 7 May 2020 Permalink | Reply
    Tags: by: Danny Roth,   

    Teaser 2869: Cubic savings 

    From The Sunday Times, 17th September 2017 [link]

    In 2009 George and Martha had a four-figure number of pounds in a special savings account (interest being paid into a separate current account). At the end of the year they decided to give some of it away, the gift being shared equally among their seven grandchildren, with each grandchild getting a whole number of pounds. At the end of the following year they did a similar thing with a different-sized gift, but again each grandchild received an equal whole number of pounds. They have repeated this procedure at the end of every year since.

    The surprising thing is that, at all times, the number of pounds in the savings account has been a perfect cube.

    What is the largest single gift received by any grandchild?

    [teaser2869]

     
    • Jim Randell 10:54 am on 7 May 2020 Permalink | Reply

      This puzzle is marked as flawed, as there are two possible solutions.

      I assumed the number of grandchildren remained constant (at 7) during the eight years in question (2009 – 2016).

      The amounts in the savings account are perfect cubes, that differ by multiples of 7, so we can collect cubes by their residue modulo 7, and consider the sets for each residue to look for 9 amounts that satisfy the remaining conditions.

      This Python program runs in 76ms.

      Run: [ @repl.it ]

      from enigma import group, irange, mod, subsets, tuples, printf
      
      # group the cubes (up to 4 digits) in descending order, by their residue mod 7
      cubes = group((i ** 3 for i in irange(21, 0, step=-1)), mod(7))
      
      # choose values for the eight gifts made (2009 - 2016)
      for s in cubes.values():
        for vs in subsets(s, size=9):
          if s[0] < 1000: continue
          # and calculate the sequence of gifts
          gs = tuple((a - b) // 7 for (a, b) in tuples(vs, 2))
          if len(set(gs)) != len(gs): continue # gift amounts are all different
          # output solutions
          m = max(gs)
          printf("{vs} -> {gs}, max = {m}")
      

      Solution: There are two solutions. The largest amount is received by a grandchild is £ 292, or £ 388.

      If we start with 5832 (= 18³) in the savings account, and then give presents of (248, 103, 292, 86, 31, 64, 8, 1) to each grandchild then the amounts remaining in the savings account are:

      5832 (= 18³)
      4096 (= 16³)
      3375 (= 15³)
      1331 (= 11³)
      729 (= 9³)
      512 (= 8³)
      64 (= 4³)
      8 (= 2³)
      1 (= 1³)

      However, starting with 8000 (= 20³) and giving (163, 278, 388, 67, 104, 112, 13, 14), leaves amounts of:

      8000 (= 20³)
      6859 (= 19³)
      4913 (= 17³)
      2197 (= 13³)
      1728 (= 12³)
      1000 (= 10³)
      216 (= 6³)
      125 (= 5³)
      27 (= 3³)

      One way to rescue the puzzle is to exclude 1 as an amount given to the grandchildren (or remaining in the account).

      Another way is to require that none of the amounts given to any grandchild is itself a perfect cube.

      Either of these restrictions eliminate the first solution, leaving a unique answer of £ 388.

      Like

    • GeoffR 8:28 am on 10 May 2020 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      % Yearly account balances
      var 1000..9999: S1; var 1..9999: S2; var 1..9999: S3;
      var 1..9999: S4; var 1..9999: S5; var 1..9999: S6;
      var 1..9999: S7; var 1..9999: S8; var 1..9999: S9;
      
      % yearly gifts 2009 - 2016
      var 1..1400: G1; var 1..999: G2; var 1..999: G3;
      var 1..999: G4; var 1..999: G5; var 1..999: G6;
      var 1..999: G7; var 1..999: G8; 
      
      % All yearly gifts are different values
      constraint all_different ([G1, G2, G3, G4, G5, G6, G7, G8]);
      
      % Set of cubes up to a maximum of four digits
      set of int: cube = {n * n * n | n in 1..21};
      
      % S1 is largest yearly account balance
      constraint increasing([S9,S8,S7,S6,S5,S4,S3,S2,S1]);
      
      % All yearly account balances are cubes
      constraint S1 in cube /\  S2 in cube /\  S3 in cube 
      /\ S4 in cube /\  S5 in cube /\  S6 in cube
      /\ S7 in cube /\  S8 in cube /\ S9 in cube;
      
      % Yearly amounts to distribute amongst seven grandchildren
      constraint (S1 - S2) mod 7 == 0 /\ (S2 - S3) mod 7 == 0 /\ 
      (S3 - S4) mod 7 == 0 /\ (S4 - S5) mod 7 == 0
      /\ (S5 - S6) mod 7 == 0 /\ (S6 - S7) mod 7 == 0 
      /\ (S7 - S8) mod 7 == 0 /\ (S8 - S9) mod 7 == 0;
      
      % Yearly total gifts to each of seven grandchildren
      constraint G1 == (S1 - S2) div 7 /\ G2 == (S2 - S3) div 7
      /\ G3 == (S3 - S4) div 7 /\ G4 == (S4 - S5) div 7
      /\ G5 == (S5 - S6) div 7 /\ G6 == (S6 - S7) div 7
      /\ G7 == (S7 - S8) div 7 /\ G8 == (S8 - S9) div 7;
      
      % Maximum yearly gift
      var 10..1000: maxv;
      maxv = max([G1, G2, G3, G4, G5, G6, G7, G8]);
       
      solve satisfy;
      
      output ["Yearly account balances: " ++ 
      show([S1, S2, S3, S4, S5, S6, S7, S8, S9])] ++ 
      ["\nYearly gifts(£): " ++ show ([G1, G2, G3, G4, G5, G6, G7, G8])]
      ++ ["\nMax gift = " ++ show(maxv)] ;
      
      % Yearly account balances: [5832, 4096, 3375, 1331, 729, 512, 64, 8, 1]
      % Yearly gifts(£): [248, 103, 292, 86, 31, 64, 8, 1]
      % Max gift = 292
      % ----------
      % Yearly account balances: [8000, 6859, 4913, 2197, 1728, 1000, 216, 125, 27]
      % Yearly gifts(£): [163, 278, 388, 67, 104, 112, 13, 14]
      % Max gift = 388
      % ----------
      % ==========
      
      
      
      

      Like

  • Jim Randell 8:29 am on 28 April 2020 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2593: Spell it out! 

    From The Sunday Times, 3rd June 2012 [link]

    I have written down a very large number (but with fewer than twenty-five digits). If you spell out each of its digits as a word, then for each digit its last letter is the same as the first letter of the next digit (the last letter of the last digit being the same as the first letter of the first digit). One example of such a number would be 83821.

    Neither my number nor the sum of its digits is a palindromic number (but in fact the original number is one more than a palindrome).

    What is my number?

    [teaser2593]

     
    • Jim Randell 8:30 am on 28 April 2020 Permalink | Reply

      This Python program runs in 99ms.

      Run: [ @repl.it ]

      from enigma import int2words, irange, is_palindrome, nsplit, printf
      
      # digits as words
      words = list(int2words(d) for d in irange(0, 9))
      
      # possible next numbers
      succ = dict()
      for (d1, w1) in enumerate(words):
        succ[d1] = list(d2 for (d2, w2) in enumerate(words) if w1[-1] == w2[0])
      
      # find numbers that form a loop according to relationship r
      def solve(ns, k, r=succ):
        # check the numbers form a loop
        if ns[0] in r[ns[-1]]:
          yield ns
        # can we add another number
        if len(ns) < k:
          for n in r[ns[-1]]:
            yield from solve(ns + [n], k)
      
      # consider possible initial digits
      for n in succ.keys():
        # find loops with length less than 25
        for ns in solve([n], 24):
          # the number itself is 1 more than a palindrome
          if not(ns[0] + 1 == ns[-1] and is_palindrome(ns[1:-1])): continue
          # the sum of the digits is not a palindrome
          t = sum(ns)
          if is_palindrome(nsplit(t)): continue
          # output solution
          printf("{ns} -> {t}")
      

      Solution: The number is 183838383838383838382.

      The number is 21 digits long. And the digit sum is (8 + 3) × 9 + (1 + 8 + 2) = 110.

      Like

  • Jim Randell 9:24 am on 23 April 2020 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2591: Shilly Chalet 

    From The Sunday Times, 20th May 2012 [link]

    George and Martha are running a holiday camp and their four daughters are staying there. To keep the peace they have been given chalets in different areas. Amelia’s chalet number is between 1 and 99, Bertha’s is between 100 and 199, Caroline’s between 200 and 299, and Dorothy’s between 300 and 399.

    George commented that the difference between any two of the four chalet numbers is either a square or a cube. Martha added that the same could be said for the sum of the chalet numbers of the three youngest daughters.

    Who is the eldest daughter and what is her chalet number?

    [teaser2591]

     
    • Jim Randell 9:25 am on 23 April 2020 Permalink | Reply

      Programatically it is straightforward to check all the possibilities.

      This Python program runs in 141ms.

      Run: [ @repl.it ]

      from enigma import is_square, is_cube, irange, cached, printf
      
      # check for a square or a cube
      check = cached(lambda n: is_square(n) or is_cube(n))
      
      # choose a value for A
      for A in irange(1, 99):
        # choose a value for B
        for B in irange(100, 199):
          if not check(B - A): continue
          # choose a value for C
          for C in irange(200, 299):
            if not(check(C - A) and check(C - B)): continue
            # choose a value for D
            for D in irange(300, 399):
              if not(check(D - A) and check(D - B) and check(D - C)): continue
              # check the total excluding the eldest
              T = A + B + C + D
              for (n, x) in zip("ABCD", (A, B, C, D)):
                if not check(T - x): continue
                printf("A={A} B={B} C={C} D={D}; eldest={n}")
      

      Solution: Amelia is the eldest daughter. Her chalet is number 93.

      The chalet numbers are:

      A=93, B=193, C=218, D=318

      And: B + C + D = 729 = 27² = 9³.

      This sum is both a square and a cube.

      So, if you interpret “either … or …” to be an exclusive or (one or the other, but not both), then the puzzle has no solutions.

      Like

    • GeoffR 10:45 am on 24 April 2020 Permalink | Reply

      
      % A Solution in MiniZinc
      include "globals.mzn";
       
      var 1..99:A;       % Amelia
      var 100..199:B;    % Bertha
      var 200..299:C;    % Caroline
      var 300..399:D;    % Dorothy
      
      set of int: sq = {n * n | n in 2..32};  
      set of int: cb = {n * n * n | n in 2..10};
      
      % difference between any chalet numbers is either a square or a cube
      constraint (B-A) in sq \/ (B-A) in cb;
      constraint (C-A) in sq \/ (C-A) in cb;
      constraint (C-B) in sq \/ (C-B) in cb;
      constraint (D-C) in sq \/ (D-C) in cb;
      constraint (D-B) in sq \/ (D-B) in cb;
      constraint (D-A) in sq \/ (D-A) in cb;
      
      % sum of three youngest daughters chalet numbers is a square or a cube
      constraint ((A+B+C) in sq \/ (A+B+C) in cb)
      \/  ((A+B+D) in sq \/ (A+B+D) in cb)
      \/  ((B+C+D) in sq \/ (B+C+D) in cb);
      
      solve satisfy;
      
      % A = 93;
      % B = 193;
      % C = 218;
      % D = 318;
      % % time elapsed: 0.06 s
      % ----------
      % ==========
      % sum of three youngest daughters chalets is a square or a cube
      % A + B + C = 93 + 193 + 218 = 504 - not a square or a cube
      % A + B + D = 93 + 193 + 318 = 604 - not a square or a cube
      % B + C + D = 193 + 218 + 318 = 729 - is both a square and a cube
      
      % Therefore, Ameila is the eldest daughter with chalet number 93
      
      
      

      Like

    • GeoffR 11:46 am on 24 April 2020 Permalink | Reply

      sq = [x * x for x in range(2,32)]
      cb = [x * x * x for x in range(2,10)]
      
      # form a set of square and cube numbers
      sc = set(sq) | set(cb)
      
      for a in range(1,100):
        for b in range(100,200):
          if (b-a) in sc:
            for c in range(200,300):
              if (c-a) in sc and (c-b) in sc:
                for d in range(300,400):
                  if (d-c) in sc and (d-b) in sc and (d-a) in sc:
                    if (a+b+d) in sc:
                      print('Eldest daughter Caroline has chalet', c)
                    if (b+c+d) in sc:
                      print('Eldest daughter Ameila has chalet', a)
                    if (a+c+d) in sc:
                        print('Eldest daughter Bertha has chalet', b)
                    if (a+b+c) in sc:
                        print('Eldest daughter Dorothy has chalet', d)
      
      # Eldest daughter Ameila has chalet 93
      
      
      

      Like

  • Jim Randell 9:42 am on 22 January 2020 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2991: Super Street 

    From The Sunday Times, 19th January 2020 [link]

    George and Martha and their five daughters with their families have moved into six houses in Super Street. I define a “super prime number” as a prime number which has at least two digits adding up to a prime number (e.g. 11 and 23). Similarly for “super squares” (e.g. 36) and “super cubes”. Houses in Super Street are numbered with the lowest 31 super numbers of the above types.

    The elderly couple live in the highest-numbered house on the street. They noticed that the last digits of their daughters’ houses were five consecutive digits and the sum of their five house numbers was a perfect square. Furthermore, the ordinal positions (lowest-numbered house is 1 and so on) of all but one of the houses were prime.

    Which five houses did the daughters occupy?

    [teaser2991]

     
    • Jim Randell 9:43 am on 22 January 2020 Permalink | Reply

      I took the definition of a “super-p” number n to be as follows:

      n has property p;
      The digit sum of n also has property p;
      n has more than 1 digit.

      This seems to be the required interpretation (a possible alternative interpretation gives no solutions).

      This Python program runs in 304ms.

      Run: [ @repl.it ]

      from heapq import merge
      from enigma import nsplit, Primes, is_prime, irange, inf, is_square, is_cube, first, uniq, subsets, tuples, printf
      
      # generate "super" numbers from iterator <s> must have at least 2
      # digits, and the digit sum must satisfy <f>
      def sup(s, f):
        for n in s:
          if n < 10: continue
          if f(sum(nsplit(n))):
            yield n
      
      # "super" primes, squares, cubes
      sp = sup(Primes(), is_prime)
      ss = sup((x ** 2 for x in irange(1, inf)), is_square)
      sc = sup((x ** 3 for x in irange(1, inf)), is_cube)
      
      # select the first 31 "super" numbers
      ns = first(uniq(merge(sp, ss, sc)), 31)
      printf("[ns={ns}]")
      
      # G+M live in the highest numbered house
      GM = ns.pop(-1)
      printf("GM = {GM}")
      
      # map the remaining numbers to ordinal values (starting at 1)
      m = dict((n, i) for (i, n) in enumerate(ns, start=1))
      
      # check a sequence is consecutive
      is_consecutive = lambda s: all(a + 1 == b for (a, b) in tuples(s, 2))
      
      # consider numbers of the five daughters
      for ds in subsets(ns, size=5):
        # sum of the numbers is a square
        if not is_square(sum(ds)): continue
        # the units digits form a consecutive sequence
        if not is_consecutive(sorted(d % 10 for d in ds)): continue
        # exactly 4 of their ordinals are prime
        if not(sum(is_prime(m[d]) for d in ds) == 4): continue
        printf("ds = {ds}")
      

      Solution: The house numbers of the daughters are: 23, 125, 137, 144, 196.

      George and Martha live at house number 199 (super-prime).

      The daughters live at the following house numbers:

      23 (super-prime, 2nd house)
      125 (super-cube, 17th house)
      137 (super-prime, 19th house)
      144 (super-square, 21st house)
      196 (super-square, 29th house)

      The sum of the house numbers is 625 (= 25²).

      And the units digits form the sequence: (3, 4, 5, 6, 7).

      The ordinal of house number 144 is not prime, but the rest are.


      If we allow single digit “super” numbers, then we get the following solution:

      George and Martha live at house number 157 (super-prime).

      The daughters live at the following house numbers:

      2 (super-prime, 2nd house)
      41 (super-prime, 13th house)
      100 (super-square, 21st house)
      113 (super-prime, 23rd house)
      144 (super-square, 29th house)

      The sum of the house numbers is 400 (= 20²).

      And the units digits form the sequence: (0, 1, 2, 3, 4).

      The ordinal of house number 100 is not prime, but the rest are.

      Like

  • Jim Randell 5:08 pm on 22 November 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2983: Maths for dessert 

    From The Sunday Times, 24th November 2019 [link]

    George and Martha have their five daughters round the dinner table. After the meal, they had ten cards numbered 0 to 9 inclusive and randomly handed two to each daughter. Each was invited to form a two-digit number. The daughter drawing 0 obviously had no choice and had to announce a multiple of ten.

    However, the others each had the choice of two options. For example if 3 and 7 were present, either 37 or 73 would be permissible. George added up the five two-digit numbers (exactly one being divisible by 9) and Martha noticed that three of the individual numbers divided exactly into that total.

    What was the total of the remaining two numbers?

    [teaser2983]

     
    • Jim Randell 5:16 pm on 22 November 2019 Permalink | Reply

      This Python program runs in 114ms.

      Run: [ @repl.it ]

      from itertools import product
      from enigma import partitions, irange, filter2, ordered, printf
      
      # form numbers from digits a and b
      def numbers(a, b):
        if a > 0: yield 10 * a + b
        if b > 0: yield 10 * b + a
      
      # deal out the 10 cards in pairs
      for ps in partitions(irange(0, 9), 2):
        # exactly one of the numbers is divisible by 9
        if sum((a + b) % 9 == 0 for (a, b) in ps) != 1: continue
        # form the numbers from the pairs
        for ns in product(*(numbers(*p) for p in ps)):
          # exactly three of the numbers divide into the total
          t = sum(ns)
          (ds, rs) = filter2((lambda n: t % n == 0), ns)
          if len(ds) != 3: continue
          # output solution
          printf("sum{rs} = {s} [numbers = {ns}, total = {t}]", rs=ordered(*rs), s=sum(rs), ns=ordered(*ns))
      

      Solution: The sum of the numbers that do not divide into the total is 147.

      The numbers are: 14, 28, 50, 63, 97.

      Of these only 63 is divisible by 9.

      The sum of the numbers is 252, which is divisible by 14, 28, and 63.

      And the remaining numbers (50 and 97) sum to 147.

      Like

    • GeoffR 9:47 am on 25 November 2019 Permalink | Reply

      
      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 1..9:A; var 1..9:B; var 1..9:C;
      var 1..9:D; var 1..9:E; var 1..9:F;
      var 1..9:G; var 1..9:H; var 1..9:I;
      
      % Make J the zero digit
      int: J == 0;
      
      constraint all_different ([A,B,C,D,E,F,G,H,I,J]);
        
      % Five 2-digit numbers 
      var 10..99: AB = 10*A + B;
      var 10..99: CD = 10*C + D;
      var 10..99: EF = 10*E + F;
      var 10..99: GH = 10*G + H;
      var 10..99: IJ = 10*I + J;
      
      var 10..400: all_dig; 
      var 10..200: dig2;   % sum of the remaining two numbers
      
      constraint all_dig = AB + CD + EF + GH + IJ;
      
      % One of the five 2-digit numbers is divisible by 9
      constraint sum ( [ AB mod 9 == 0, CD mod 9 == 0, 
      EF mod 9 == 0, GH mod 9 == 0, IJ mod 9 == 0 ] ) = 1;
      
      % Three of the 2-digit numbers divide the five digit total
      constraint all_dig mod AB == 0 /\ all_dig mod CD == 0 
      /\ all_dig mod EF == 0 /\ all_dig mod GH != 0 /\ all_dig mod IJ != 0;
      
      % Sum of two digits which do not divide the five digit total
      constraint  dig2 == GH + IJ ;
      
      solve satisfy;
      
      output [ "Total of the remaining two numbers = " ++ show(dig2)
      ++ "\nTotal of five 2-digit numbers = " ++ show(all_dig)++ "\n"
      ++"The five numbers are " ++ show(AB) ++ ", " ++ show(CD) ++ ", " 
      ++ show(EF) ++ ", " ++ show(GH) ++ " and " ++ show(IJ) ];
      
      % Total of the remaining two numbers = 147
      % Total of five 2-digit numbers = 252
      % The five numbers are 28, 14, 63, 97 and 50
      
      
      
      

      Like

    • GeoffR 7:56 am on 28 November 2019 Permalink | Reply

      
      from itertools import permutations
      
      for p in permutations('1234567890'):
        a, b, c, d, e, f, g, h, i, j = p
        
        ab, cd, ef = int(a + b), int(c + d), int(e + f)
        gh, ij = int(g + h), int(i + j)
      
        # check all five numbers are 2-digit numbers
        n5 = (ab, cd, ef, gh, ij)
        if all( x < 100 and x >= 10 for x in n5):
          tot = ab + cd + ef + gh + ij
      
          # two conditions to check
          if (sum(1 for y in n5 if y % 9 == 0) == 1 
            and sum(1 for z in n5 if tot % z == 0) == 3) :
               
            if (tot % ab == 0 and tot % cd == 0 and tot % ef == 0
              and tot % gh != 0 and tot % ij != 0) :
              print(f"Three factors are {ab}, {cd} and {ef}" )
              print(f"Two remaining numbers are {gh} and {ij} (total {gh+ij})")
              break    # to stop repeated answers
      
      # Three factors are 14, 28 and 63
      # Two remaining numbers are 50 and 97 (total 147)
      
      

      Like

  • Jim Randell 3:03 pm on 11 October 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2977: Enjoying retirement 

    From The Sunday Times, 13th October 2019 [link]

    George and Martha have worked on separate departments of a company which has four-digit telephone extensions. George looked at his extension and it was ABCD. Martha’s (larger) also had A, B and C as her first three digits but not necessarily in that order. Her last digit was E. They added up their two four-digit numbers and found that the least significant digit was F. They then looked at the difference and that was a four-digit number of which the least significant digit was G. They then looked at the product and the least significant digit was H. They then looked at the average of the extensions; in it the first two digits were equal, the last two digits were also equal, and the least significant digit was J. I have thus mentioned nine digits, all positive and unequal.

    What was Martha’s extension?

    [teaser2977]

     
    • Jim Randell 3:34 pm on 11 October 2019 Permalink | Reply

      I assumed that the average of the two extension numbers was a whole number, so both extension numbers must have the same parity.

      The following Python program runs in 92ms.

      Run: [ @repl.it ]

      from enigma import irange, subsets, nconcat, nsplit, div, printf
      
      # allowable digits
      digits = set(irange(1, 9))
      
      # check digits are allowable and all different
      def check(*ds):
        return len(ds) + len(digits.difference(ds)) == len(digits)
      
      # consider digits D and E, which must have the same parity
      for (D, E) in subsets(digits, size=2, select="P"):
        if not(D % 2 == E % 2): continue
      
        # the sum ends in F, difference ends in G, the product ends in H
        (F, G, H) = (n % 10 for n in (D + E, E - D, D * E))
        if not check(D, E, F, G, H): continue
      
        # choose first three digits A, B, C to give ABCD = George's extension
        for (A, B, C) in subsets(digits.difference((D, E, F, G, H)), size=3, select="P"):
          xG = nconcat(A, B, C, D)
      
          # and permute ABC to give XYZ, where XYZE = Martha's extension
          for (X, Y, Z) in subsets((A, B, C), size=3, select="P"):
            xM = nconcat(X, Y, Z, E)
      
            # George's number is less than Martha's, difference is 4 digits
            if xM - xG < 1000: continue
      
            # average ...
            avg = nsplit(div(xG + xM,  2))
            # has first 2 and last 2 digits equal
            if not(avg[0] == avg[1] and avg[-2] == avg[-1]): continue
            # and the final digit is J
            J = avg[-1]
            if not check(A, B, C, D, E, F, G, H, J): continue
      
            printf("George = {xG}, Martha = {xM} [A={A} B={B} C={C} D={D} E={E} F={F} H={H} J={J}]")
      

      Solution: Martha’s extension number is 8563.

      George’s extension number is 6859.

      So if George’s number is ABCD, then Martha’s is BCAE.

      The sum is 15422, which ends in F=2.

      The difference is 1704, which ends in G=4.

      The product is 58733617, which ends in H=7.

      And the average (mean) is 7711, which starts with two 7’s and ends with two J’s; J=1.

      Each non-zero digit is mentioned once. We have (1, 2, 3, 4, 5, 6, 7, 8, 9) = (J, F, E, G, C, A, H, B, D).

      Like

    • GeoffR 9:31 am on 13 October 2019 Permalink | Reply

      
      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 1..9: A; var 1..9: B; var 1..9: C;  
      var 1..9: D; var 1..9: E; var 1..9: F;    
      var 1..9: G; var 1..9: H; var 1..9: J;
      
      constraint all_different([A, B, C, D, E, F, G, H, J]);
      
      % George's extension number
      var 1000..9999: george = 1000*A + 100*B + 10*C + D; 
      
      % Martha's extension number
      var 1000..9999: martha ;
      
      % Average of George's and Martha's numbera
      var 1000..9999: av ; 
       
      constraint av == (martha + george) div 2;
      constraint martha > george;
      
      % Martha's extension had the first three digits A,B,C in some order
      % Martha's 1st Digit
      constraint 
         martha div 1000 == A 
      \/ martha div 1000 == B 
      \/ martha div 1000 == C;
      
      % Martha's 2nd Digit
      constraint 
         ((martha div 100) mod 10) == A
      \/ ((martha div 100) mod 10) == B
      \/ ((martha div 100) mod 10) == C;
      
      % Martha's 3rd Digit
      constraint 
         ((martha div 10) mod 10) == A
      \/ ((martha div 10) mod 10) == B
      \/ ((martha div 10) mod 10) == C;
      
      % Martha's 4th Digit
      constraint martha mod 10 == E;
      
      % Sum of george and martha has F as least significant digit
      constraint (george + martha) mod 10 == F;
      
      % Difference of george and martha has G as least significant digit
      constraint (martha - george) > 1000  
      /\ (martha - george) mod  10 == G;
      
      % Product of george and martha has H as least significant digit
      constraint (martha * george) mod 10 == H;
      
      % Average has first 2 digits equal
      constraint av div 1000 ==  (av div 100) mod 10;
        
      % Average has last 2 digits equal to J
      constraint (av div 10) mod 10 == J /\ av mod 10 = J;
      
      solve satisfy;
      
      output [ "Martha's extension is " ++ show(martha) 
      ++ "\n" ++ "George's extension is " ++ show(george)
      ++ "\n" ++ "Average of two extensions is " ++ show(av)];
      
      % Martha's extension is 8563
      % George's extension is 6859
      % Average of two extensions is 7711
      % ----------
      % ==========
      
      

      Like

  • Jim Randell 8:18 am on 7 October 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2837: Back and forth 

    From The Sunday Times, 5th February 2017 [link]

    George and Martha have a digital 24-hour clock that always displays the time as four digits (e.g. 2:17am displays as 0217). During one lazy weekend George noted two particular times when the four-digit display was palindromic. He calculated the number of minutes from the first of these times to the second and he discovered that the answer was a three-figure palindrome. When he reported all the details to Martha, she commented that the sum of the eleven digits in the three palindromes was also palindromic.

    What were the two palindromic times?

    [teaser2837]

     
    • Jim Randell 8:19 am on 7 October 2019 Permalink | Reply

      This program considers when there is a corresponding minute for each hour to make a list of palindromic times, and then looks at pairs of times from this list that satisfy the remaining conditions.

      It runs in 44ms.

      Run: [ @repl.it ]

      from itertools import product
      from enigma import irange, nsplit, concat, printf
      
      # palindrome check
      is_palindrome = lambda s: s[::-1] == s
      
      # record palindromic times
      ts = list()
      for h in irange(0, 23):
        (a, b) = nsplit(h, 2)
        m = 10 * b + a
        # record time (in minutes) and displayed digits
        if m < 60: ts.append((h * 60 + m, (a, b, b, a)))
      
      # now consider two palindromic times (the second time could be the following day)
      for ((t1, ds1), (t2, ds2), t3) in product(ts, ts, (0, 1440)):
      
        # calculate the difference in minutes
        t = t2 + t3 - t1
      
        # it should be a 3-digit palindrome
        if not(99 < t < 1000): continue
        ds = nsplit(t)
        if not is_palindrome(ds): continue
      
        # calculate the sum of the digits, it should also be a palindrome
        s = sum(ds1) + sum(ds2) + sum(ds)
        if not is_palindrome(nsplit(s)): continue
      
        # output a solution
        printf("{ds1} -> {ds2}{x} = {t} minutes, digit sum = {s}", ds1=concat(ds1), ds2=concat(ds2), x=(" (next day)" if t3 else ""))
      

      Solution: The two times were 1001 and 0110 (the following day).

      The first time is 10:01am on one day (displayed as 1001), the second time is 1:10am the following day (displayed as 0110). The difference between these times is 15 hours and 9 minutes = 909 minutes. And the sum of the digits in 1001, 0110, 909 is 22.

      Like

  • Jim Randell 11:58 am on 30 September 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2842: The best policy 

    From The Sunday Times, 12th March 2017 [link]

    George and Martha’s home insurance policy number is a six-figure number consisting of six different digits. George commented that the number was divisible by each of its digits and also by the sum of its digits. Martha then added that, if you deleted the left-hand digit, then you were left with a five-figure number divisible by the sum of its five digits. If you then deleted that number’s left-hand digit, then you were left with a four-figure number divisible by the sum of its four digits, and so on all the way down.

    What is their policy number?

    [teaser2842]

     
    • Jim Randell 11:59 am on 30 September 2019 Permalink | Reply

      Using copy and paste we can easily make the expressions to feed to the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      The following run file executes in 78ms.

      Run: [ @repl.it ]

      #!/usr/bin/env python -m enigma -r
      
      # suppose the number is: ABCDEF
      
      SubstitutedExpression
      
      --digits="1-9"
      --answer="ABCDEF"
      
      "ABCDEF % A = 0"
      "ABCDEF % B = 0"
      "ABCDEF % C = 0"
      "ABCDEF % D = 0"
      "ABCDEF % E = 0"
      "ABCDEF % F = 0"
      "ABCDEF % (A + B + C + D + E + F) = 0"
      "BCDEF % (B + C + D + E + F) = 0"
      "CDEF % (C + D + E + F) = 0"
      "DEF % (D + E + F) = 0"
      "EF % (E + F) = 0"
      

      Solution: The policy number is 384912.


      I also coded up a custom program for this particular problem.

      It runs in 44ms. So it is faster, but the execution time saved is only a fraction of a second, so you could argue it isn’t worth the extra effort for writing the program. Nevertheless, here it is:

      # permissible digits (0 is disallowed as n % 0 is undefined)
      digits = range(1, 10)
      
      # find <k> digit numbers such that each suffix is divisible by the sum
      # of the digits in that suffix and the number is divisible by each of
      # it's digits individually.
      def solve(k, n=0, s=0, ds=[]):
        # are we done?
        if k == 0:
          # check for divisibility by all the digits individually
          if all(n % d == 0 for d in ds):
            print(n)
        else:
          # add a new digit to the front
          for d in digits:
            if d not in ds:
              ds1 = [d] + ds
              n1 = n + d * 10 ** len(ds)
              s1 = s + d
              if n1 % s1 == 0:
                # and solve for the remaining digits
                solve(k - 1, n1, s1, ds1)
      
      # we need 6 digit numbers
      solve(6)
      

      We can however use this program to investigate numbers of different lengths, and we find that 6 is the maximum possible length.

      Like

  • Jim Randell 8:29 am on 13 September 2019 Permalink | Reply
    Tags: by: Danny Roth,   

    Teaser 2783: Old boys’ banquet 

    From The Sunday Times, 24th January 2016 [link]

    George and Martha have arranged the seating plan for the annual Old Boys banquet; it involves a number of tables, each seating 50 diners. More than half the Old Boys are bringing one female guest each and the rest are coming alone. Martha wrote down three numbers, namely the number of Old Boys bringing a guest, the number of Old Boys coming alone, and the total number of Old Boys coming. George noted that the three numbers between them used each of the digits 0 to 9 exactly once.

    How many Old Boys are bringing a guest, and how many are coming alone?

    [teaser2783]

     
    • Jim Randell 8:30 am on 13 September 2019 Permalink | Reply

      If s is the number of old boys without guests and g is the number with guests, then we have a pandigital sum of the form:

      s + g = b

      where s < g.

      Altogether there are 10 digits used so, alphametically, the sum is one of:

      AB + CDEF = GHIJ
      ABC + DEF = GHIJ

      This Python program uses the [[ SubstitutedSum() ]] solver from the enigma.py library to examine solutions to both sums. It runs in 277ms.

      Run: [ @repl.it ]

      from enigma import SubstitutedSum, div, printf
      
      # solve the pandigital sum
      digits = 'ABCDEFGHIJ'
      for k in (2, 3):
        (x, y, z) = (digits[0:k], digits[k:6], digits[6:])
        p = SubstitutedSum([x, y], z)
        for s in p.solve():
          # turn the solution into numbers
          (s, g, b) = (int(p.substitute(s, w)) for w in (x, y, z))
          # more than half the old boys have guests
          if not(g > s): continue
          # so the total number of people is...
          t = b + g
          # and the number of tables is...
          n = div(t, 50)
          if n is None: continue
        
          printf("s={s} g={g} boys={b}, people={t} tables={n}")
      

      Solution: There are four possible solutions:

      26 without guests, 4987 with guests; 5013 total boys, 10000 total people, 200 tables
      74 without guests, 5938 with guests; 6012 total boys, 11950 total people, 239 tables
      86 without guests, 1957 with guests; 2043 total boys, 4000 total people, 80 tables
      346 without guests, 752 with guests; 1098 total boys, 1850 total people, 37 tables

      I suspect the setter intended the final solution to be the correct answer, which is the only solution where the pandigital sum is of the form: ABC + DEF = GHIJ.

      A suitable upper limit on the total number of old boys, total number of people, or number of tables would eliminate the other solutions.

      However if we change the condition in the puzzle text to:

      More than half the Old Boys are coming alone and the rest are bringing one female guest each.

      (i.e. we require s > g).

      Then there is only a single solution to the puzzle:

      746 without guests, 352 with guests; 1098 total boys, 1450 total people, 29 tables

      Reversing the inequality at line 12 of the program will give this solution.

      Like

    • GeoffR 1:59 pm on 14 September 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn"; 
      
      var 0..9: a; var 0..9: b; var 0..9: c; var 0..9: d; var 0..9: e;
      var 0..9: f; var 0..9: g; var 0..9: h; var 0..9: i; var 0..9: j;
      
      % Assume boys/boys with guest/total boys are in ratio 3:3:4
      var 100..999: abc;     % boys with guest
      var 100..999: def;     % boys alone
      var 1000..2000: ghij;  % total boys
      var 0..250: tables;    % total tables
      
      % All ten digits are used exactly once
      constraint alldifferent([a,b,c,d,e,f,g,h,i,j]) 
                 /\ a > 0 /\ d > 0 /\ g > 0;
      
      constraint  abc = 100*a + 10*b + c
               /\ def = 100*d + 10*e + f
               /\ ghij = 1000*g + 100*h + 10*i + j ;
      
      % More than half the boys brought a female guest
      constraint abc > ghij div 2;
      
      constraint abc + def == ghij;
      
      constraint tables * 50 == abc * 2 + def;
      
      solve satisfy;
      
      output [" Boys with a guest: " ++ show(abc) ++ "\n" ++
              " Boys on their own: " ++ show(def) ++ "\n" ++
              " Total boys: " ++ show(ghij) ++ "\n" ++
              " Tables: " ++ show(tables)];  
      
      % Boys with a guest: 752
      % Boys on their own: 346
      % Total boys: 1098
      % Tables: 37
      % ----------
      % ==========
      
      

      Like

  • Jim Randell 5:56 pm on 6 September 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2972: A relaxing day 

    From The Sunday Times, 8th September 2019 [link]

    George and Martha have a digital clock, which displays time with six digits on the 24-hour system (i.e. HH:MM:SS).

    One afternoon, George looked at the clock and saw a six-digit display involving six different positive digits. He dozed off immediately, and when he awoke in the evening he saw another display of six digits, again all positive and different. He dozed off immediately and later on (before midnight) he awoke, having slept for exactly 23 minutes longer than the previous time. At that time, he saw a third display, yet again six different positive digits. He thus had seen eighteen digits and the nine positive digits had each appeared exactly twice.

    At what time did George wake up after his first sleep?

    [teaser2972]

     
    • Jim Randell 6:30 pm on 6 September 2019 Permalink | Reply

      This Python program looks for possible 6-digit times composed of different digits, it separates them into afternoon (before 6pm) and evening (after 6pm) and the looks for two times in the evening that have a difference that is 23 minutes longer than the difference between the first time and one of the afternoon times. We then check the three times between them use each of the digits exactly twice. It runs in 460ms.

      Run: [ @repl.it ]

      from itertools import product
      from enigma import irange, nsplit, subsets, multiset, sprintf, printf
      
      # format a number of seconds as HH:MM:SS
      def hms(t):
        (h, m, s) = nsplit(t, 3, base=60)
        return sprintf("{h:02d}:{m:02d}:{s:02d}")
      
      # consider 2-digit numbers with different digits that make valid times
      (hs, mss) = (list(), list())
      for n in irange(12, 59):
        (a, b) = nsplit(n, 2)
        if a == b or b == 0: continue
        if n < 24: hs.append((a, b))
        mss.append((a, b))
      
      # collect times composed of 6 different digits
      (aft, eve) = (dict(), dict())
      for ((h1, h0), (m1, m0), (s1, s0)) in product(hs, mss, mss):
        ds = (h1, h0, m1, m0, s1, s0)
        if len(set(ds)) != 6: continue
        # time as a number of seconds
        t = ((h1 * 10 + h0) * 60 + (m1 * 10 + m0)) * 60 + (s1 * 10 + s0)
        (aft if t < 64800 else eve)[t] = ds
      
      # find times t2, t3, both in the evening
      for (t2, t3) in subsets(sorted(eve.keys()), size=2):
        d = t3 - t2 - 1380
        if not(d > 0): continue
        # and t1 in the afternoon
        t1 = t2 - d
        if t1 not in aft: continue
      
        # check each digit is used exactly twice
        m = multiset(aft[t1], eve[t2], eve[t3])
        if not all(v == 2 for v in m.values()): continue
      
        # output solution
        printf("{t1} -> {t2} -> {t3}", t1=hms(t1), t2=hms(t2), t3=hms(t3))
      

      Solution: After the first nap George awoke when the clock read 19:56:48.

      There are two possible start times for the first nap (although they are within a minute of each other), but in both cases the wake time from the first nap is the same, and so there is a unique answer to the puzzle.

      The two possible sequences are:

      16:27:39 → (3h29m09s) → 19:56:48 → (3h52m09s) → 23:48:57
      16:28:37 → (3h28m11s) → 19:56:48 → (3h51m11s) → 23:47:59

      And these are the only two sequences even if we don’t restrict the first time to be “afternoon” and the final two times to be “evening”.

      Like

    • GeoffR 3:33 pm on 10 September 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      % hours, min and sec for afternoon time
      var 12..17: ah;
      var 12..59: am;
      var 12..59: as;
      
      % No zeroes in six positive digits
      constraint am != 20 /\ am != 30 /\ am != 40 /\ am != 50;
      constraint as != 20 /\ as != 30 /\ as != 40 /\ as != 50;
      
      constraint  all_different([ah div 10, ah mod 10,
      am div 10, am mod 10, as div 10, as mod 10]);
      
      % afternoon time in sec (range from midday to midnight)
      var 43000..90000: a_sec = ah*3600 + am*60 + as;
      
      % hours, min and sec for 1st evening time 
      var 18..23: eh1;
      var 12..59: em1;
      var 12..59: es1;
      
      constraint eh1 != 20;
      
      % No zeroes in six positive digits of time
      constraint em1 != 20 /\ em1 != 30 /\ em1 != 40 /\ em1 != 50;
      constraint es1 != 20 /\ es1 != 30 /\ es1 != 40 /\ es1 != 50;
      
      constraint all_different ([eh1 div 10, eh1 mod 10,
      em1 div 10, em1 mod 10, es1 div 10, es1 mod 10]);
      
      % 1st evening time in sec
      var 43000..90000: e1_sec = eh1*3600 + em1*60 + es1;
      
      % 2nd evening time 
      % hours, min and sec for 2nd evening time
      var 18..23: eh2;
      var 12..59: em2;
      var 12..59: es2;
      
      constraint all_different ([eh2 div 10, eh2 mod 10,
      em2 div 10, em2 mod 10, es2 div 10, es2 mod 10]);
      
      constraint eh2 != 20;
      
      % No zeroes in six positive digits
      constraint em2 != 20 /\ em2 != 30 /\ em2 != 40 /\ em2 != 50;
      constraint es2 != 20 /\ es2 != 30 /\ es2 != 40 /\ es2 != 50;
      
      % 2nd evening time in sec
      var 43000..90000: e2_sec = eh2*3600 + em2*60 + es2;
      
      % all digits 1..9 in the three 6-digit times occur exactly twice
      constraint forall(i in 1..9) 
      (count ([ 
      ah div 10, ah mod 10,am div 10, am mod 10, as div 10, as mod 10,
      eh1 div 10, eh1 mod 10,em1 div 10, em1 mod 10, es1 div 10, es1 mod 10,
      eh2 div 10, eh2 mod 10, em2 div 10, em2 mod 10, es2 div 10, es2 mod 10
              ], i, 2) );
      
      % 2nd time span is 23 minutes longer than the 1st time span
      constraint (e1_sec - a_sec) ==  (e2_sec - e1_sec) - 23 * 60;
      
      solve satisfy;
      
      output  [ "Time are in format [hh mm ss] " ++ "\n" ++
      show ([ah, am, as])  ++ " " ++ show(a_sec) ++ " total sec"
      ++"\n" ++ show([eh1, em1, es1]) ++ " " ++ show(e1_sec) ++ " total sec"
      ++"\n" ++ show([eh2, em2, es2]) ++ " " ++ show(e2_sec) ++ " total sec"
      ++"\n" ++ "George woke up after his first sleep at " 
      ++ show(eh1) ++ ":" ++ show(em1) ++ ":" ++ show(es1)  ];
      
      % Time are in format [hh mm ss] 
      % [16, 27, 39] 59259 total sec
      % [19, 56, 48] 71808 total sec
      % [23, 48, 57] 85737 total sec
      % George woke up after his first sleep at 19:56:48
      % ----------
      % Time are in format [hh mm ss] 
      % [16, 28, 37] 59317 total sec
      % [19, 56, 48] 71808 total sec
      % [23, 47, 59] 85679 total sec
      % George woke up after his first sleep at 19:56:48
      % ----------
      % ==========
      
      
      

      Like

  • Jim Randell 12:01 pm on 26 August 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2818: Accountability 

    From The Sunday Times, 25th September 2016 [link]

    George and Martha’s bank account number is an 8-digit number consisting of the digits 1 to 8 in some order.

    Martha commented that, if you split the number into two 4-figure numbers, then the number formed by the last four digits is a multiple of the number formed by the first four digits.

    Then George listed all the different prime numbers that divided exactly into the account number. When he added together all those primes the total was less than a hundred.

    What is their account number?

    [teaser2818]

     
    • Jim Randell 12:01 pm on 26 August 2019 Permalink | Reply

      We can solve this puzzle using the general alphametic solver [[ SubstitutedExpression() ]] from the enigma.py library.

      The following run file executes in 218ms.

      Run: [ @repl.it ]

      #!/usr/bin/env python -m enigma -r
      
      SubstitutedExpression
      
      # solver paraemters
      --digits="1-8"
      --answer="ABCDEFGH"
      
      # expressions to solve
      "EFGH % ABCD = 0"
      "sum(p for (p, e) in prime_factor(ABCDEFGH)) < 100"
      

      Solution: The account number is 12876435.

      The number factorises as:

      12876435 = 3³.5.11.13.23.29

      So the sum of the prime divisors is 84.

      Like

  • Jim Randell 9:54 am on 21 August 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2824: New extension 

    From The Sunday Times, 6th November 2016 [link]

    George has just moved departments and he has a new four-figure telephone extension number. He shows it to Martha and proudly points out that, if you delete any two of the digits of the extension number, then the remaining two-figure number is prime. Martha then lists the resulting six different primes and comments delightedly that more than one of them divides exactly into the extension number.

    What is George’s new extension number?

    [teaser2824]

     
    • Jim Randell 9:55 am on 21 August 2019 Permalink | Reply

      We can express the puzzle as a set of alphametic constraints and use the [[ SubstitutedExpression() ]] solver from the enigma.py library to solve it.

      The following run file executes in 81ms.

      Run: [ @repl.it ]

      #!/usr/bin/env python -m enigma -r
      
      # solver to use
      SubstitutedExpression
      
      # solver parameters
      --distinct=""
      --invalid=""
      --answer="ABCD"
      
      # 2-digit subsequences are prime
      "is_prime(AB)"
      "is_prime(AC)"
      "is_prime(AD)"
      "is_prime(BC)"
      "is_prime(BD)"
      "is_prime(CD)"
      
      # and all different
      "all_different(AB, AC, AD, BC, BD, CD)"
      
      # and more than 1 of them divides ABCD
      "sum(ABCD % x == 0 for x in (AB, AC, AD, BC, BD, CD)) > 1"
      

      Solution: George’s new extension number is 4371.

      4371 is divisible by 47 and by 31.

      Like

    • GeoffR 8:43 am on 22 August 2019 Permalink | Reply

      
      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 1..9:A; var 1..9:B; var 1..9:C;  var 1..9:D;
      
      predicate is_prime(var int: x) = 
      x > 1 /\ forall(i in 2..1 + ceil(sqrt(int2float(ub(x))))) 
      ((i < x) -> (x mod i > 0));
      
      % the four-figure telephone extension number
      var 1000..9999: ABCD = 1000*A + 100*B + 10*C + D;
      
      % six different two-digit numbers
      constraint all_different([AB, AC, AD, BC, BD, CD]);
      
      var 10..99: AB = 10*A + B;
      var 10..99: AC = 10*A + C; 
      var 10..99: AD = 10*A + D;
      var 10..99: BC = 10*B + C;
      var 10..99: BD = 10*B + D;
      var 10..99: CD = 10*C + D;
      
      constraint is_prime(AB) /\ is_prime(AC) /\ is_prime(AD)
      /\ is_prime(BC) /\ is_prime(BD) /\ is_prime(CD);
      
      % more than one two-digit number divides exactly into the extension number
      constraint sum ([ABCD mod AB == 0, ABCD mod AC == 0,
      ABCD mod AD == 0, ABCD mod BC == 0, ABCD mod BD == 0,
      ABCD mod CD == 0]) > 1;
      
      solve satisfy;
      output ["George's Ext No. = " ++ show(ABCD)];
      
      % George's Ext No. = 4371
      % ----------
      % ==========
      
      

      Like

  • Jim Randell 8:13 pm on 9 August 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2968: Gardening division 

    From The Sunday Times, 11th August 2019 [link]

    George and Martha’s garden is a perfect square of length (whole number of metres) a two-digit number AB. The area is a three-digit number CDE. In the middle, they have planted a square flowerbed of a length which is a single-digit number F and area a two-digit number GH.

    They have called in a gardener, who works for a single-digit I hours. He works for a whole number of minutes on the flowerbed and the remainder on the surrounding lawn. Each square metre of the flowerbed requires N (a single digit) times the time spent on each square metre of the surrounding lawn. I have mentioned nine letters, A-I inclusive, and each stands for a different positive digit.

    How many minutes does the gardener work on the lawn?

    [teaser2968]

     
    • Jim Randell 8:29 pm on 9 August 2019 Permalink | Reply

      We can express the puzzle as a set of alphametic constraints and then use the general alphametic solver [[ SubstitutedExpression() ]] from the enigma.py library to find the solution.

      The following run file executes in 140ms.

      #!/usr/bin/env python -m enigma -r
      
      SubstitutedExpression
      
      --distinct="ABCDEFGHI"
      --digits="1-9"
      
      "AB ** 2 = CDE"
      "F ** 2 = GH"
      
      "div(CDE - GH + N * GH, I * 60)"
      
      --answer="div((CDE - GH) * I * 60, CDE - GH + N * GH)"
      

      Solution: The gardener worked on the lawn for 99 minutes.

      The garden is a square of side 24m, giving a total area of 576m².

      The flowerbed has sides of 9m, so has an area of 81m², leaving an area of 495m² of lawn.

      The gardener works on the flowerbed for 81 minutes, at a rate of 1 minute per square metre of flowerbed. He then works on the lawn 5 times faster, at a rate of 1 minute per 5 square metres of lawn, so the 495m² of lawn takes 99 minutes. The total time is therefore 180 minutes, or 3 hours.

      Like

  • Jim Randell 9:33 am on 12 July 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2803: Easy as ABC 

    From The Sunday Times, 12th June 2016 [link]

    George and Martha have replaced the digits 0 to 9 by the letters A to J in some order. George then noted a neat product, namely:

    AB × CDE = FGHIJ

    Then Martha noted a neat sum, namely:

    AB + CD + EF + GH + IJ = CCC

    What, in order, are the values of the letters A to J?

    [teaser2803]

     
    • Jim Randell 9:34 am on 12 July 2019 Permalink | Reply

      When this puzzle was published (June 2016) I wrote a couple of programs to solve it using the [[ SubstitutedSum() ]] solver from the enigma.py (which itself was originally written to solve Enigma 63 and similar puzzles).

      However, shortly afterwards I started work on a solver for general alphametic expressions in Python, and this puzzle was one of the examples I used to test it. I wrote up my thoughts as Solving Alphametics with Python and Solving Alphametics with Python, Part 2. And although there have been many incremental improvements to the code over the last 3 years, the ideas from Part 2 still form the basis of the [[ SubstitutedExpression() ]] solver in the enigma.py library, which I have used it to solve a wide variety of alphametic puzzles in that time.

      For this puzzle we can use the following command line (which executes in 160ms):

      Run: [ @repl.it ]

      % python enigma.py SubstitutedExpression --answer="ABCDEFGHIJ" "AB * CDE = FGHIJ" "AB + CD + EF + GH + IJ = CCC"
      (AB * CDE = FGHIJ) (AB + CD + EF + GH + IJ = CCC) (ABCDEFGHIJ)
      (52 * 367 = 19084) (52 + 36 + 71 + 90 + 84 = 333) (5236719084) / A=5 B=2 C=3 D=6 E=7 F=1 G=9 H=0 I=8 J=4
      ABCDEFGHIJ = 5236719084 [1 solution]
      

      Solution: The values of the letters are: A=5 B=2 C=3 D=6 E=7 F=1 G=9 H=0 I=8 J=4.

      Like

    • GeoffR 11:18 am on 12 July 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 0..9:A; var 0..9:B; var 0..9:C; var 0..9:D;
      var 0..9:E; var 0..9:F; var 0..9:G; var 0..9:H;
      var 0..9:I; var 0..9:J;
      
      constraint A > 0 /\ C > 0 /\ E > 0 /\ F > 0
      /\ G > 0 /\ I > 0;
      
      constraint all_different ([A, B, C, D, E, F, G, H, I]);
      
      var 10..99: AB = 10*A + B;
      var 10..99: CD = 10*C + D;
      var 10..99: EF = 10*E + F;
      var 10..99: GH = 10*G + H;
      var 10..99: IJ = 10*I + J;
      var 100..999: CCC = 111*C;
      var 100..999: CDE = 100*C + 10*D + E;
      var 10000..99999: FGHIJ = 10000* F + 1000*G + 100*H + 10*I + J;
      
      % two alphametic equations to solve
      constraint AB * CDE == FGHIJ;
      constraint AB + CD + EF + GH + IJ == CCC;
      
      solve satisfy;
      
      output ["A,B,C,D,E,F,G,H,I,J = " ++ show([A,B,C,D,E,F,G,H,I,J])]
      ++ ["\n" ++ show(AB) ++ " * " ++ show(CDE) ++ " = " ++ show(FGHIJ)]
      ++ ["\n" ++ show (AB) ++ " + " ++  show(CD) ++ " + " ++ show(EF) ++ " + "
      ++ show(GH) ++ "  + " ++ show(IJ) ++ " = "  ++ show(CCC) ] ;
      
      % A,B,C,D,E,F,G,H,I,J = [5, 2, 3, 6, 7, 1, 9, 0, 8, 4]
      % 52 * 367 = 19084
      % 52 + 36 + 71 + 90  + 84 = 333
      % ----------
      % ==========
      
      
      

      Like

  • Jim Randell 8:26 am on 5 July 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2901: Square deal 

    From The Sunday Times, 29th April 2018 [link]

    George and Martha have five daughters who have periodically appeared in my teasers over the years. They are all working for the same company and have perfect-square four-digit telephone extensions, in all five cases. The letters ABCDEFGHIJ stand for the digits 0-9 but in no particular order. The extensions are as follows:

    Andrea = IBHC
    Bertha = DJJC
    Caroline = BAFH
    Dorothy = GFID
    Elizabeth = GAEE

    What are the five extensions?

    [teaser2901]

     
    • Jim Randell 8:27 am on 5 July 2019 Permalink | Reply

      This is a straightforward alphametic problem which can be handled directly by the [[ SubstitutedExpression() ]] solver in the enigma.py library.

      The following run file executes in 127ms.

      Run: [ @repl.it ]

      #!/usr/bin/env python -m enigma -r
      
      SubstitutedExpression
      
      --answer="(IBHC, DJJC, BAFH, GFID, GAEE)"
      
      "is_square(IBHC)"
      "is_square(DJJC)"
      "is_square(BAFH)"
      "is_square(GFID)"
      "is_square(GAEE)"
      

      Solution: The five extension numbers are: 2916, 5776, 9801, 3025, 3844.

      Like

    • GeoffR 12:13 pm on 5 July 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
       
      var 0..9: A; var 0..9: B; var 0..9: C; var 0..9: D;
      var 0..9: E; var 0..9: F; var 0..9: G; var 0..9: H;
      var 0..9: I; var 0..9: J;
      
      constraint all_different ([A,B,C,D,E,F,G,H,I,J]);
      constraint I > 0 /\ D > 0 /\ B > 0 /\ G > 0;
      
      set of int: sq4 = {n*n | n in 32..99};
      
      % The five extensions
      var 1000..9999: IBHC = 1000*I + 100*B + 10*H + C;
      var 1000..9999: DJJC = 1000*D + 100*J + 10*J + C;
      var 1000..9999: BAFH = 1000*B + 100*A + 10*F + H;
      var 1000..9999: GFID = 1000*G + 100*F + 10*I + D;
      var 1000..9999: GAEE = 1000*G + 100*A + 10*E + E;
      
      constraint IBHC in sq4 /\ DJJC in sq4 /\ BAFH in sq4
      /\ GFID in sq4 /\ GAEE in sq4;
      
      solve satisfy;
      
      output [ "The five extensions are " ++ show(IBHC) ++ "," ++ show(DJJC) 
      ++ "," ++ show(BAFH) ++ "," ++ show(GFID) ++ " and " ++ show(GAEE) ];
      
      % The five extensions are 2916,5776,9801,3025 and 3844
      % % time elapsed: 0.02 s
      % ----------
      % ==========
      % Finished in 437msec
      

      Like

  • Jim Randell 8:16 pm on 31 May 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2958: Sudoku crossword 

    From The Sunday Times, 2nd June 2019 [link]

    George and Martha are doing a mathematical crossword. There is a 3×3 grid with the numbers 1 to 9 inclusive appearing once each. The clues are as follows:

    Across:
    top line: a prime number
    middle line: a prime number
    bottom line: a prime number

    Down:
    left column: a perfect square
    middle column: a perfect square
    right column: a prime number

    Although you do not need to know this, one of the diagonal three-digit numbers is also prime.

    What is the sum of the three “across” numbers?

    [teaser2958]

     
    • Jim Randell 8:18 pm on 31 May 2019 Permalink | Reply

      We can solve this using the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      This run file executes in 180ms.

      Run: [ @repl.it ]

      #!/usr/bin/env python -m enigma -r
      
      # consider the grid:
      #
      #  A B C
      #  D E F
      #  G H I
      
      SubstitutedExpression
      
      --digits="1-9"
      
      "is_prime(ABC)"
      "is_prime(DEF)"
      "is_prime(GHI)"
      
      "is_square(ADG)"
      "is_square(BEH)"
      "is_prime(CFI)"
      
      --answer="ABC + DEF + GHI"
      

      Solution: The sum of the three across numbers is 1449.

      The grid is:

      2 8 3
      5 4 7
      6 1 9

      The across numbers are: 283 (prime), 547 (prime), 619 (prime), and their sum is 1449.

      The down numbers are: 256 (square), 841 (square), 379 (prime), and their sum is 1476.

      The diagonals can be read (left to right) as 249 and 643, and the second of these is prime.

      There are no further solutions if the digit 0 is not excluded.

      Like

    • GeoffR 8:43 am on 21 June 2019 Permalink | Reply

      
      % A Solution in MiniZinc
      include "globals.mzn"; 
      
      %  Grid
      %  A B C
      %  D E F
      %  G H I
      
      var 1..9:A; var 1..9:B; var 1..9:C; 
      var 1..9:D; var 1..9:E; var 1..9:F; 
      var 1..9:G; var 1..9:H; var 1..9:I; 
      
      constraint all_different ( [A,B,C,D,E,F,G,H,I]);
      
      % Rows
      var 100..999: ABC = 100*A + 10*B + C;
      var 100..999: DEF = 100*D + 10*E + F;
      var 100..999: GHI = 100*G + 10*H + I;
      
      % Columns
      var 100..999: ADG = 100*A + 10*D + G;
      var 100..999: BEH = 100*B + 10*E + H;
      var 100..999: CFI = 100*C + 10*F + I;
      
      predicate is_prime(var int: x) = 
      x > 1 /\ forall(i in 2..1 + ceil(sqrt(int2float(ub(x))))) 
      ((i < x) -> (x mod i > 0));
      
      set of int: sq3 = {n*n | n in 10..31};
      
      % Rows
      constraint is_prime(ABC) /\ is_prime(DEF) /\ is_prime(GHI);
      
      % Columns
      constraint ADG in sq3 /\ BEH in sq3 /\ is_prime(CFI);
      
      solve satisfy;
      
      output [ "Rows total is "++ show(ABC + DEF + GHI) ]
      ++ [ "\nRows are "++ show(ABC)  ++ ", " ++ show(DEF) ++ 
      " and " ++ show (GHI) ];
      
      % Rows total is 1449
      % Rows are 283, 547 and 619
      % time elapsed: 0.02 s
       %----------
      % ==========
      % Finished in 253msec
      

      Like

  • Jim Randell 3:40 pm on 1 May 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2917: Polygoland 

    From The Sunday Times, 19th August 2018 [link]

    We’ve all heard of Heligoland but George and Martha are on holiday in Polygoland. This is an island and when it was first inhabited, the authorities created as many national parks as possible subject to the restriction that each such park will be a regular polygon with the angle between each side being an integral number of degrees, and all the parks have different numbers of sides. Walking along the border between two such parks, Martha commented that the angle (A) of one of them was an exact multiple of the number of sides (S) in the other. George mentioned that the multiple was equal to the number of parks on the island.

    What are A and S?

    [teaser2917]

     
    • Jim Randell 3:40 pm on 1 May 2019 Permalink | Reply

      For a regular n-gon, the internal angles are (180 – 360 / n) degrees.

      So we can determine the number of possible n-gons with integer angles t from the number of divisors of 360 (greater than 2).

      There are 22 possible polygons, so t = 22

      So we need to find a solution to the equation:

      180 – 360 / n = 22m
      n = 360 / (180 – 22m)

      where n is a divisor of 360 (greater than 2).

      There are only a few values of m to consider and only one of them gives a viable value for n.

      Run: [ @repl.it ]

      from enigma import divisors, irange, div, printf
      
      # find divisors of 360 where n > 2
      ns = list(n for n in divisors(360) if n > 2)
      t = len(ns)
      printf("[{t} different polygons]")
      
      # now consider possible values of m
      for m in irange(1, 180 // t):
        n = div(360, 180 - t * m)
        if n is None or n == m or n not in ns: continue
        printf("A={A} degrees, S={m} [m={m} n={n}]", A=(180 - 360 // n))
      

      Solution: A = 176°, S = 8.

      The solution to the equation is m = 8, which gives a value of n = 90.

      The angle 176° is 4° off a straight line, so if we walk along the perimeter each side turns us by 4°. After 90 sides we have turned through 360°.

      176 = 22 × 8, and 8 is a divisor of 360, so there will be an octagonal park (with interior angles of 180° – 45° = 135°).

      Like

  • Jim Randell 12:55 pm on 17 April 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2923: Powerful numbers 

    From The Sunday Times, 30th September 2018 [link]

    George and Martha’s five daughters have been investigating large powers of numbers. Each daughter told the parents that they had worked out a number which was equal to its last digit raised to an exact power. When Andrea announced her power, the parents had a 50% chance of guessing the last digit. When Bertha announced a larger power, the same applied. When Caroline announced her power, the parents had only a 25% chance of guessing the last digit; with Dorothy’s larger power, the same applied. When Elizabeth announced hers, the parents only had a 12.5% chance of guessing the last digit. I can tell you that the five powers were consecutive two-digit numbers adding up to a perfect square.

    What, in alphabetical order of the daughters, were the five powers?

    [teaser2923]

     
    • Jim Randell 12:55 pm on 17 April 2019 Permalink | Reply

      We ignore the digits 0 and 1 (as 0^k = 0 and 1^k = 1 for positive k), which leaves the digits 2 to 9.

      A chance of 50% is 1 out of 2, 25% is 1 out of 4, and 12.5% is 1 out of 8, so we are looking for a collection of consecutive numbers where 2 numbers have a choice from 2, another 2 have a choice from 4, and the remaining number has a choice from 8.

      This Python program looks at sequences of 5 consecutive 2-digit numbers, and when it finds one that sums to a square it checks that the choices for the digits conform to this pattern.

      It runs in 71ms.

      Run: [ @repl.it ]

      from enigma import irange, tuples, is_square, icount, printf
      
      # consider 5-sequences of consecutive 2-digit numbers for the powers
      for ks in tuples(irange(10, 99), 5):
        # the 5 powers sum to a square
        if is_square(sum(ks)) is None: continue
      
        # find the number of digits (ignoring 0 and 1) where d^k mod 10 = d
        ns = list(icount(irange(2, 9), (lambda d: pow(d, k, 10) == d)) for k in ks)
        if sorted(ns) != [2, 2, 4, 4, 8]: continue
      
        # extract indices for the given value
        indices = lambda v: (i for (i, n) in enumerate(ns) if n == v)
      
        # A has the first 2, B has the second 2
        (A, B) = indices(2)
        # C has the first 4, D has the second 4
        (C, D) = indices(4)
        # E has the 8
        (E,) = indices(8)
        
        printf("A={A} B={B} C={C} D={D} E={E}", A=ks[A], B=ks[B], C=ks[C], D=ks[D], E=ks[E])
      

      Solution: The five powers are: A=44, B=46, C=43, D=47, E=45.

      There are only three sequences that sum to a square:

      (18, 19, 20, 21, 22) → 10²
      (43, 44, 45, 46, 47) → 15²
      (78, 79, 80, 81, 82) → 20²

      And only one of these gives the right set of choices when raising the digits 2-9 to the corresponding powers.


      Analytically:

      If we consider digits d from 2 to 9, and look at increasing powers k such that d^k end in the digit d we get:

      k=1: d=2, 3, 4, 5, 6, 7, 8, 9
      k=2: d=5, 6
      k=3: d=4, 5, 6, 9
      k=4: d=5, 6
      k=5: d=2, 3, 4, 5, 6, 7, 8, 9
      k=6: d=5, 6
      k=7: d=4, 5, 6, 9
      k=8: d=5, 6
      k=9: d=2, 3, 4, 5, 6, 7, 8, 9
      k=10: d=5, 6

      We see that there is a repeating pattern, by count of the number of digits, of: (8, 2, 4, 2)…

      So for powers of: 1, 5, 9, 13, 17, … there is a choice of 8 possible digits (a 12.5% chance).

      For powers of: 2, 4, 6, 8, 10, 12, … there is a choice of 2 possible digits (a 50% chance).

      For powers of: 3, 7, 11, 15, … there is a choice of 4 possible digits (a 25% chance).

      The five girls have chosen 5 consecutive powers with two 50% chances (2), two 25% chances (4) and one 12.5% chance (8), so the part of the sequence they have chosen is … (4, 2, 8, 2, 4).

      We know the 8’s occur when k = 4n + 1.

      So the powers the girls have chosen are:

      (4n – 1, 4n, 4n + 1, 4n + 2, 4n + 3)

      These are 2-digit numbers, which limits n to the range [3, 24].

      The sum of the powers is:

      20n + 5

      and this needs to be a square number.

      >>> list(n for n in irange(3, 24) if is_square(20 * n + 5))
      [11]
      

      So, n = 11, and the girls numbers (and digits counts) are:

      43 (4), 44 (2), 45 (8), 46 (2), 47 (4)

      A and B both have counts of 2, C and D both have counts of 4, E has a count of 8.

      Like

  • Jim Randell 7:04 am on 27 March 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2905: Trackword 

    From The Sunday Times, 27th May 2018 [link]

    George and Martha are tackling a Trackword problem which appears in magazines. Nine letters are placed in a 3×3 grid and you have to work from one square to a neighbour, proceeding up, down, left, right or diagonally until all nine squares have been visited to form a nine-letter word. You must start in the top-left corner. As an example, you can get the word EIGHTFOLD from the following grid:

    George and Martha thought that would be interesting to work out how many possible routes there are which start in the top-left corner.

    How many routes are there?

    [teaser2905]

     
    • Jim Randell 7:05 am on 27 March 2019 Permalink | Reply

      (See also: Grid Puzzle)

      There’s a handy [[ grid_adjacency() ]] function in the enigma.py library to compute the adjacency matrix on a square grid.

      This Python program can be used to calculate the number of paths on an m×n grid. For the 3×3 grid it runs in 81ms.

      Run: [ @repl.it ]

      from enigma import grid_adjacency, icount, arg, printf
      
      # consider an m x n grid
      m = arg(3, 0, int)
      n = arg(m, 1, int)
      
      # adjacency matrix
      adj = grid_adjacency(m, n, include_diagonal=1)
      
      # generate paths with k additional steps, prefix p, visiting different squares
      def paths(k, p):
        # are we done?
        if k == 0:
          yield p
        else:
          # extend the path
          for x in adj[p[-1]]:
            if x not in p:
              yield from paths(k - 1, p + [x])
      
      # count maximal length paths that start at square 0
      k = m * n - 1
      t = icount(paths(k, [0]))
      printf("[{m}x{n}] total paths = {t}")
      

      Solution: There are 138 different possible routes.

      From square 0 we can go to to the central square (4) or to an edge square (1 or 3), so we can just count the paths with prefix [0, 4] and [0, 1]. There will be the same number of paths with prefix [0, 3] as there are with prefix [0, 1].

      >>> icount(paths(7, [0, 4])) + 2 * icount(paths(7, [0, 1]))
      138
      

      Like

  • Jim Randell 7:45 am on 13 March 2019 Permalink | Reply
    Tags: by: Danny Roth   

    Teaser 2936: Multicoloured 

    From The Sunday Times, 30th December 2018 [link]

    George and Martha are selling wall-paper of various colours. By replacing letters with positive digits, they have devised the following multiplication problem:

    RED × GREY = YELLOW

    The N in GREEN is the remaining positive digit. The red wall-paper is sold only in squares, which is appropriate since RED is a perfect square.

    What is the value of GREEN?

    [teaser2936]

     
    • Jim Randell 7:47 am on 13 March 2019 Permalink | Reply

      We can use the [[ SubstitutedExpression() ]] solver from the enigma.py library to solve the alphametic expressions directly.

      This run-file executes in 119ms.

      Run: [ @repl.it ]

      #!/usr/bin/env python -m enigma -r
      
      SubstitutedExpression
      
      --digits="1-9"
      --answer="GREEN"
      
      "RED * GREY = YELLOW"
      "is_square(RED)" # optional
      

      Solution: GREEN = 21668.

      The [[ is_square(RED) ]] condition is optional (in that there are no further solutions if it is omitted), but it verifies the statement of the problem, and also allows the run-file to execute a little faster (and is convenient when pursuing a manual solution).

      Like

    • GeoffR 12:12 pm on 13 March 2019 Permalink | Reply

      % A solution in MinZinc 
      include "globals.mzn";
      
      var 1..9:R; var 1..9:E; var 1..9:D; var 1..9:G; var 1..9:Y; 
      var 1..9:L; var 1..9:O; var 1..9:W; var 1..9:N; 
      
      constraint all_different([R, E, D, G, Y, L, O, W, N]);
      
      var 100..999: RED = 100*R + 10*E + D;
      var 1000..9999: GREY = 1000*G + 100*R + 10*E + Y;
      var 100000..999999: YELLOW = 100000*Y + 10000*E + 1000*L + 100*L + 10*O + W;
      var 10000..99999: GREEN =10000*G + 1000*R + 110*E + N;
      
      set of int: sq3 = {n*n | n in 10..31};
      constraint RED in sq3;
      
      constraint RED * GREY == YELLOW;
      
      solve satisfy;
      
      output [ "GREEN = " ++ show(GREEN)  ++ "\n"
      ++ show(RED) ++ " X " ++ show(GREY) ++ " = " ++ show(YELLOW)];
      
      % GREEN = 21668
      % 169 X 2163 = 365547
      % time elapsed: 0.02 s
      
      
      

      Like

c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
Create your website at WordPress.com
Get started
%d bloggers like this: