Updates from Jim Randell Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 6:17 am on 17 March 2019 Permalink | Reply
    Tags:   

    Teaser 2947: 55 Divisions 

    From The Sunday Times, 17th March 2019 [link] [link]

    To mark her 55th birthday, Martha, a school teacher, gave each of her nine pupils a sheet of paper with a single different digit from 1 to 9 written on it.

    They stood at the front of the classroom in a row and the 9-digit number on display was divisible by 55. Martha then asked the first 3 in the row (from the left) to sit down. The remaining 6-digit number was also divisible by 55. The next 3 then sat down and the remaining 3-digit number was also divisible by 55.

    The 9 digit number was the smallest possible. What was it?

    [teaser2947]

     
    • Jim Randell's avatar

      Jim Randell 6:25 am on 17 March 2019 Permalink | Reply

      We can treat the problem as an alphametic puzzle, use the [[ SubstitutedExpression() ]] solver from the enigma.py library to find all possible solutions, and then find the smallest of these.

      This Python program runs in 98ms.

      Run: [ @replit ]

      from enigma import (SubstitutedExpression, Accumulator, irange, printf)
      
      # the alphametic puzzle
      p = SubstitutedExpression(
        [ "ABCDEFGHI % 55 = 0", "DEFGHI % 55 = 0", "GHI % 55 = 0" ],
        answer="ABCDEFGHI",
        digits=irange(1, 9),
      )
      
      # find the minimum answer
      r = Accumulator(fn=min).accumulate_from(p.answers())
      
      # output solution
      printf("min answer = {r.value} [of {r.count} solutions]")
      

      Solution: The number is 143869275.

      There are 48 different solutions to the alphametic puzzle.

      Like

    • GeoffR's avatar

      GeoffR 2:46 pm on 19 March 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      enum letters = {A, B, C, D, E, F, G, H, I};  
      array [letters] of var 1..9: v;
      
      constraint all_different(v);
      
      var 100000000..999999999: ABCDEFGHI = v[A] * pow(10,8) + v[B] * pow(10,7) 
      + v[C] * pow(10,6) + v[D] * pow(10,5) + v[E] * pow(10,4) + v[F] * 1000 
      + v[G] * 100 + v[H] * 10 + v[I];
      
      var 100000..999999: DEFGHI = 100000 * v[D] + 10000 * v[E] + 1000 * v[F] 
      + 100 * v[G] + 10 * v[H] + v[I];
      
      var 100..999: GHI = 100 * v[G] + 10 * v[H] + v[I];
      
      constraint ABCDEFGHI mod 55 == 0 /\ DEFGHI mod 55 == 0 /\ GHI mod 55 == 0;
      
      solve minimize(ABCDEFGHI);
      
      output ["Smallest 9-digit number = " ++ show(ABCDEFGHI) ];
      
      % Smallest 9-digit number = 143869275
      % time elapsed: 0.03 s
      % ----------
      % ==========
      % Finished in 241msec
      
      
      

      Like

      • Jim Randell's avatar

        Jim Randell 11:09 am on 20 March 2019 Permalink | Reply

        This puzzle is an ideal candidate for using the [[ solve minimize(...) ]] target in a MiniZinc model.

        Also I didn’t know MiniZinc had [[ enum ]]. (In fact, in the tutorial I used I seem to remember there was a section on how it didn’t have them and how to emulate them. I suppose they must have come along in a later version).

        Like

    • GeoffR's avatar

      GeoffR 12:14 pm on 20 March 2019 Permalink | Reply

      The latest version of MiniZinc( Ver 2.2.3) has much improved documentation and a new menu, including timing for Windows and other features. It seems odd that a solution can be found in 20 -30 msec, but still takes over 200msec to finish.

      Here is the link for enums:

      https://www.minizinc.org/doc-2.2.3/en/spec.html#enumerated-types

      Like

    • Jim Randell's avatar

      Jim Randell 10:29 am on 29 July 2020 Permalink | Reply

      I’ve recently added the [[ accumulate ]] parameter to the [[ SubstitutedExpression() ]] solver, which allows values to be computed from all the solutions.

      So, my Python program above can be modified to:

      from enigma import (SubstitutedExpression, irange, printf)
      
      # the alphametic puzzle
      p = SubstitutedExpression(
        [ "ABCDEFGHI % 55 = 0", "DEFGHI % 55 = 0", "GHI % 55 = 0" ],
        digits=irange(1, 9),
        answer="ABCDEFGHI",
        accumulate=min,
      )
      
      # solve the puzzle
      r = p.run()
      
      # output solution
      printf("min answer = {r.accumulate} [of {r.n} values]")
      

      Although the accumulated value will be output twice.

      We can also achieve the same result using a run file:

      Run: [ @replit ]

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --digits="1-9"
      
      "ABCDEFGHI % 55 = 0"
      "DEFGHI % 55 = 0"
      "GHI % 55 = 0"
      
      --answer="ABCDEFGHI"
      --accumulate="min"
      

      Note that changing the [[ --accumulate ]] parameter to [[ --accumulate="(min, max)" ]] allows us to calculate the minimum and maximum values from the answers.

      This functionality is available in the 2020-07-29 version of the enigma.py library.

      Like

  • Unknown's avatar

    Jim Randell 8:04 am on 16 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 464: Home meadow 

    From The Sunday Times, 19th April 1970 [link]

    The triangular home meadow at Cowpleasure Farm is bounded West and South by fences running due north and due east from the farmhouse; its other fence forms one side of a square field known as Starvecrow. The south fence of Home Meadow is the shared north boundary of two contiguous square fields, Paddock and Rookery, whose total area is just half that of Starvecrow.

    Farmer Nettle has just refenced the whole outer perimeter (i.e. excluding fences common to two fields). He used 146 equal sections of fencing, none of which needed bending or cutting.

    He plans to replace the other fences next year using the same type of section.

    How many will he need? (Don’t worry about gates; they are incorporated in some of the standard sections).

    This puzzle is included in the book Sunday Times Brain Teasers (1974).

    [teaser464]

     
    • Jim Randell's avatar

      Jim Randell 8:06 am on 16 March 2019 Permalink | Reply

      There’s nothing to distinguish the fields P and R, so we’ll call the smaller one P.

      For the square fields P, R, S, we’ll indicate the size of one side also by P, R, S, and the remaining boundary of H can be Q.

      The amount of perimeter fencing (shown in red) required is X:

      X = 3S + 2P + 2R + (R − P) + Q = 3(S + R) + P + Q

      And the amount of internal fencing (the remaining black lines) required is Y:

      Y = 2P + R + S

      This Python program uses the [[ pythagorean_triples() ]] routine (see Teaser 2910) from the enigma.py library to find possible dimensions of field H, and then determines the dimensions of the other fields.

      It runs in 77ms.

      Run: [ @repl.it ]

      from enigma import pythagorean_triples, irange, printf
      
      for (x, y, z) in pythagorean_triples(48):
        # S is the hypotenuse
        S = z
        # one of the other two sides is P + R
        for (PR, Q) in [(x, y), (y, x)]:
          # suppose P < R
          for P in irange(1, PR // 2):
            R = PR - P
            # P^2 + R^2 = S^2 / 2
            if not (2 * (P * P + R * R) == S * S): continue
            # total sum of perimeter fences is 146
            X = 3 * (S + R) + P + Q
            if not (X == 146): continue
            # sum of the internal fences
            Y = S + PR + P
            # output solution
            printf("Y={Y}, S={S} P={P} R={R} Q={Q}")
      

      Solution: He will need 57 sections.

      Like

  • Unknown's avatar

    Jim Randell 8:36 am on 15 March 2019 Permalink | Reply
    Tags:   

    Teaser 2934: Good arraz, Baz! 

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

    Baz’s three darts hit the board, scoring different numbers from 1 to 20. “Curious numbers”, said Kaz. Baz looked puzzled. Kaz explained that the first dart’s score to the power of the second dart’s score is a value that contains each numeral 0 to 9 at least once and has the third dart’s score number of digits. Baz only saw that the third dart’s score was the difference between the other two darts’ scores. Kaz wrote the full value on a beer mat. Then Baz put his glass on it and covered most of the value, leaving just the first dart’s score showing to the right and the second dart’s score to the left.

    What did each dart score in the order thrown?

    [teaser2934]

     
    • Jim Randell's avatar

      Jim Randell 8:36 am on 15 March 2019 Permalink | Reply

      This Python program runs in 75ms.

      Run: [ @repl.it ]

      from itertools import permutations
      from enigma import (irange, printf)
      
      # possible scores
      darts = set(irange(1, 20))
      
      # consider different scores for the first two darts
      for (d1, d2) in permutations(darts, 2):
      
        # "the third dart's score was the difference between the other two darts' scores"
        d3 = abs(d1 - d2)
        if d3 == d1 or d3 == d2 or d3 < 10: continue
      
        # "the first dart's score to the power of the second dart's score is a value that contains
        # each digit 0 to 9 at least once and has the third dart's score number of digits"
        x = str(d1**d2)
        if len(x) != d3: continue
        if len(set(x)) != 10: continue
      
        # "the first dart's score showing to the right and the second dart's score to the left."
        # assuming "right" = "least significant digits"
        # and "left" = "most significant digits"
        if not (x.endswith(str(d1)) and x.startswith(str(d2))): continue
      
        # output solution
        printf("darts = ({d1}, {d2}, {d3}) [{d1}^{d2} = {x}]")
      
      

      Solution: The scores were: 5, 19, 14.

      We have:

      5^19 = 19073486328125

      Which starts with 19, and ends in 5.

      Like

  • Unknown's avatar

    Jim Randell 6:59 am on 14 March 2019 Permalink | Reply
    Tags: by: Fred Neville   

    Brainteaser 1795: Dicey columns 

    From The Sunday Times, 9th February 1997 [link]

    A boy amused himself by building three separate columns of some equal-sized dice. In each column each die was placed squarely on the one below it. He then looked at the tops of the columns, read each as a digit, and then read the digits together to form one long number.

    For example, had the tops been:

    then he would have read 113.

    He was surprised to find that the number which he read equalled the total number of visible spots all around and on top of his three columns of dice. He also multiplied together the three numbers from the tops of the columns and found that the answer equalled the total number of dice which he had used.

    What was that total number of visible spots?

     

    For a more challenging Teaser try to find a corresponding situation with more than three columns of dice. There is only one other possibility.

     

    The text of this puzzle is taken from the book Brainteasers (2002), so may differ from the puzzle originally published in the newspaper.

    In fact, the puzzle published in the paper was the more challenging variation.

    [teaser1795]

     
    • Jim Randell's avatar

      Jim Randell 7:01 am on 14 March 2019 Permalink | Reply

      Suppose the tops of the three columns show A, B, C.

      Opposite faces on a die sum to 7, so each die shows 14 spots on the vertical sides, and the top dice also show A, B, C, so if there are n dice the total number of spots visible is:

      14n + (A + B + C) = ABC

      (where ABC is an alphametic expression).

      Also the number of dice is given by:

      n = A × B × C

      which gives us the following alphametic expression to solve:

      (14 × A × B × C) + (A + B + C) = ABC

      where A, B, C are limited to be digits from 1 to 6.

      This can easily be solved using the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      Run: [ @repl.it ]

      >>> python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "14 * (A * B * C) + (A + B + C) = ABC"
      (14 * (A * B * C) + (A + B + C) = ABC)
      (14 * (1 * 3 * 3) + (1 + 3 + 3) = 133) / A=1 B=3 C=3
      [1 solution]
      

      Solution: The total number of visible spots was 133.

      So there are 9 dice in total (3 columns of 3 dice each).

      In the book the puzzle then goes on to suggest:

      For a more challenging Teaser try to find a corresponding situation with more than three columns of dice. There is only one other possibility.

      We can try the same thing with four dice, showing A, B, C, D:

      >>> python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "14 * (A * B * C * D) + (A + B + C + D) = ABCD"
      (14 * (A * B * C * D) + (A + B + C + D) = ABCD)
      (14 * (2 * 5 * 3 * 6) + (2 + 5 + 3 + 6) = 2536) / A=2 B=5 C=3 D=6
      [1 solution]
      

      So the solution to this extra puzzle is with 180 dice (4 columns of 45 dice each), showing 2536 visible spots.

      There are no solutions for 5 dice, at least not reading the numbers on top of the dice as a base 10 number. If we read them as a base 8 number then there are 5 solutions with 5 dice (and 1 with 4 dice, and 4 with 3 dice). (You can try it by adding a [[ --base=8 ]] argument to the commands).

      Like

      • Jim Randell's avatar

        Jim Randell 2:43 pm on 14 March 2019 Permalink | Reply

        Writing:

        (14 × A × B × C) + (A + B + C) = 100 × A + 10 × B + C

        we can simplify this to:

        (99 × A + 9 × B) / (14 × A × B) = C

        So we only needs to consider values of A and B to derive C:

        % python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "div(99 * A + 9 * B, 14 * A * B) = C
        (div(99 * A + 9 * B, 14 * A * B) = C)
        (div(99 * 1 + 9 * 3, 14 * 1 * 3) = 3) / A=1 B=3 C=3
        [1 solution]
        

        The improvement in run time (if any) is negligible.


        However, this gives us a manual way to solve the puzzle.

        C is an integer between 1 and 6, and as the denominator of the expression for C has a divisor of 7 then so must the numerator. In fact it must be the case that 7 divides (11A + B). So for any given value of A there is only a single value for B that is possible, from which we can calculate potential values for C:

        A = 1 → B = 3 → C = 3 (Solution)
        A = 2 → B = 6 → C = 3/2
        A = 3 → B = 2 → C = 15/4
        A = 4 → B = 5 → C = 63/40
        A = 5 → B = 1 → C = 36/5
        A = 6 → B = 4 → C = 15/8

        And only one value for A gives a viable value for C.

        Like

    • GeoffR's avatar

      GeoffR 7:29 pm on 8 August 2019 Permalink | Reply

      For three columns of dice:

      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 1..6: t1; var 1..6: t2; var 1..6: t3;  % top numbers on 3 dice
      var 1..20: n;  % number of dice per column
      
      % total number of visible spots for 3 columns
      constraint 3 * (2 * 7 * n) + t1 + t2 + t3 == 100*t1 + 10*t2 + t3;
      
      % the three numbers from the tops of the three columns mutiplied
      % together give the total number of dice
      constraint t1 * t2 * t3 == 3 * n;
      
      solve satisfy;
      
      output ["Total number of visible spots = " ++ 
      show(3 * (2 * 7 * n) + t1 + t2 + t3)
      ++"\nTotal number of dice = " ++ show(n * 3) ];
      
      % Total number of visible spots = 133
      % Number of dice = 9
      % ----------
      % ==========
      

      For four columns of dice:

      % A Solution in MiniZinc
      include "globals.mzn";
      
      % top numbers on four dice
      var 1..6: t1; var 1..6: t2; var 1..6: t3; var 1..6: t4;
      var 1..75: n;  % number of dice per column
      
      % total number of visible spots for four columns
      constraint 4 * (2 * 7 * n) + t1 + t2 + t3 + t4 
      == 1000*t1 + 100*t2 + 10*t3 + t4;
      
      % the four numbers from the tops of the four columns mutiplied
      % together give total number of dice
      constraint t1 * t2 * t3 * t4 == 4 * n;
      
      solve satisfy;
      
      output ["Total number of visible spots = " ++ 
      show(4 * (2 * 7 * n) + t1 + t2 + t3 + t4)
      ++"\nTotal Number of dice = " ++ show(n * 4)
      ++"\nTop die numbers are " ++ show(t1) ++ ", " ++ show(t2)
      ++ ", " ++ show(t3) ++ " and " ++ show(t4) ];
      
      % Total number of visible spots = 2536
      % Total Number of dice = 180
      % Top die numbers are 2, 5, 3 and 6
      % ----------
      % ==========
      
      

      Like

  • Unknown's avatar

    Jim Randell 7:45 am on 13 March 2019 Permalink | Reply
    Tags:   

    Teaser 2936: Multicoloured 

    From The Sunday Times, 30th December 2018 [link] [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's avatar

      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 ]

      #! python3 -m enigma -rr
      
      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's avatar

      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

  • Unknown's avatar

    Jim Randell 6:57 am on 12 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 463: Betting prices 

    From The Sunday Times, 12th April 1970 [link]

    In the third race, the bookmakers’ prices varied considerably and, in some cases, were unusual. At one time or another up to the start of the race, the odds quoted against one or more of the 9 horses were 2 to 1, 3 to 1, 4 to 1, and all other whole numbers to 1, up to and including 28 to 1 (i.e., 27 different prices in all).

    Just before the “off” the Baron saw his chance. The prices then being offered by different bookmakers were such that, by staking a total of less than £100, and placing a whole number of pounds on each of the 9 runners he was able to ensure that, no matter which horse won, he would make an overall profit of exactly £13.

    One horse was clear favourite. The other 8 were “paired” in the betting (i.e., there were 4 pairs, both horses in each pair being at the same price — the 4 prices all being different).

    How much did the Baron stake in all, and what were the 5 prices at which he placed his bets?

    This puzzle is included in the book Sunday Times Brain Teasers (1974).

    [teaser463]

     
    • Jim Randell's avatar

      Jim Randell 6:58 am on 12 March 2019 Permalink | Reply

      This Python program collects together odds and stakes that would give the same winnings, and then looks for a collection of five that would give a profit of £13 as described.

      It runs in 76ms.

      Run: [ @repl.it ]

      from collections import defaultdict
      from itertools import combinations
      from enigma import irange, printf
      
      # record bets = (odds, stake) by winnings
      d = defaultdict(list)
      
      # consider odds of "X to 1"
      for X in irange(2, 28):
        # if x pounds is bet...
        for x in irange(1, 99):
          # winnings are...
          w = x * (X + 1)
          if w < 22: continue
          if w > 112: break
          d[w].append((X, x))
      
      # numbers of bets at lengthening odds
      ns = (1, 2, 2, 2, 2)
      
      # choose a collection of winnings and odds
      for (w, vs) in d.items():
        # choose 5 different odds
        for bets in combinations(vs, len(ns)):
          # check the winnings = stake + profit
          if not (w == sum(n * x for (n, (_, x)) in zip(ns, bets)) + 13): continue
          # output solution
          printf("winnings = {w} -> (odds, stakes) = {bets}")
      

      Solution: The Baron staked bets totalling £71. The bets were placed at odds of: 3-1, 6-1, 13-1, 20-1, 27-1.

      The bets were:

      £21 at 3-1
      £12 at 6-1 [×2]
      £6 at 13-1 [×2]
      £4 at 20-1 [×2]
      £3 at 27-1 [×2]

      Giving a total stake of £71, and a total winnings of £84 should any single bet come in.

      Like

  • Unknown's avatar

    Jim Randell 6:49 am on 11 March 2019 Permalink | Reply
    Tags:   

    Teaser 2937: Long division 

    From The Sunday Times, 6th January 2019 [link] [link]

    I wrote down a 2-digit number and a 5-digit number and then carried out a long division.

    I then erased all of the digits in the calculation, other than the 1’s, and so finished up with the image above.

    If I told you how many different digits I had erased, then you should be able to work out my two original numbers.

    What were my two original numbers?

    [teaser2937]

     
    • Jim Randell's avatar

      Jim Randell 6:52 am on 11 March 2019 Permalink | Reply

      Here’s a solution using the [[ SubstitutedDivision() ]] and [[ filter_unique() ]] functions from the enigma.py library.

      This program runs in 63ms. (Internal runtime is 7.2ms).

      Run: [ @replit ]

      from enigma import (SubstitutedDivision, filter_unique, printf)
      
      # the division sum
      p = SubstitutedDivision(
        "????1 / ?? = 1???",
        [ "?? - ?? = ?1", "?1? - 1?? = ??", "??? - ??? = 11", "111 - 111 = 0" ],
        digits=(0, 2, 3, 4, 5, 6, 7, 8, 9),
        verbose="T",  # show candidate solutions
      )
      
      # find solutions unique by the number of digits involved
      f = lambda s: len(set(s.s.values()))
      g = lambda s: (s.a, s.b)
      ss = filter_unique(p.solve(), f, g).unique
      
      # output solutions
      for s in ss:
        printf("SOLUTION: {s.a} / {s.b} = {s.c} [{n} digits]", n=f(s))
      

      Solution: The two original numbers were 37 and 58571.

      The diagram can describe 3 possible divisions:

      58201 ÷ 37 = 1573
      58571 ÷ 37 = 1583
      58941 ÷ 37 = 1593

      The first and third of these have 8 different digits in the long division sum, the second one uses 9 different digits and so gives the solution.

      Although the puzzle states that the erased digits are not 1 (and the program ensures this), there are no further solutions to the more general problem where the erased digits may be 1. We can see this by adding [[ 1 ]] in the [[ digits ]] specification on line 7 (or just removing that line completely to allow any digit to be used).

      Like

    • GeoffR's avatar

      GeoffR 7:16 pm on 14 March 2019 Permalink | Reply

      This solution found the same three possible solutions

      However, only the solution 58571 / 37 = 1583 had a unique number of digits erased by the setter, as the other two solutions had the same number of digits erased. The two digit number is therefore 37 and the five digit number is 58571.

      % A Solution in MiniZinc
      include "globals.mzn";                   
      
      %        w c d e         1 5 8 3
      %      ---------       ----------    
      %  a b)f g h i w    3 7)5 8 5 7 1
      %      a b              3 7
      %      ---              ---
      %      m 1 h            2 1 5
      %      w p q            1 8 5
      %      -----            -----          
      %        r s i            3 0 7
      %        t u v            2 9 6 
      %        -----            -----   
      %          1 1 1            1 1 1
      %          1 1 1            1 1 1 
      %          =====            =====
                                                                                                                                          
      int: w == 1;
      
      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;
      var 0..9: k; var 0..9: m; var 0..9: p; var 0..9: q; var 0..9: r; 
      var 0..9: s; var 0..9: t; var 0..9: u; var 0..9: v;
       
      constraint a > 0 /\ j > 0 /\ m > 0 /\ r > 0 /\ t > 0;
      
      var 10..99: ab = 10*a + b;
      var 1000..1999: wcde = 1000*1 + c*100 + d*10 + e;
      var 10000..99999: fghiw = 10000*f + 1000*g + 100*h + 10*i + w;
      
      var 10..99: jk = 10*j + k;
      var 100..999: m1h = 100*m + 10^1 + h;
      var 100..199: wpq = 100*1 + 10*p + q;
      var 100..999: rsi = 100*r + 10*s + i;
      var 100..999: tuv = 100*t + 10*u + v;
      
      var 10..99: rs = 10*r + s;
      var 10..99: m1 = 10*m + 1;
      var 10..99: fg = 10*f + g;
      
      constraint ab * wcde == fghiw;
      constraint fg - ab == m1;
      constraint c * ab = wpq /\ m1h - wpq == rs;
      
      constraint d * ab == tuv /\ rsi - tuv == 11;
      constraint e * ab == 111;
      
      % variables used in programme - all erased by setter (but not including w = 1)
      var set of int: s1 = {a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v};  
      
      solve satisfy;
      
      output [ show(fghiw) ++ " / " ++ show (ab) ++ " = " ++ show(wcde) 
      ++ ", digit set used (exc w=1) = " ++ show(s1) ++ "\n"
      ++ "\n[a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ]  "
      ++ "\n" ++  show ( [a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ] )];  % excludes w = 1
      
      % 58201 / 37 = 1573, digit set used (exc w=1) = {0,2,3,5,7,8,9}
      % 7 no. digit variables used, not inc 1
      
      % [a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ]  
      % [3, 7, 5, 7, 3, 5, 8, 2, 0, 2, 8, 5, 2, 7, 2, 5, 9]
      % % time elapsed: 0.02 s
      % ----------
      % 58571 / 37 = 1583, digit set used (exc w=1) = {0,2,3,5,6,7,8,9} - ANSWER
      % 8 no. digit variables used, not inc 1
      
      % [a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ]  
      % [3, 7, 5, 8, 3, 5, 8, 5, 7, 2, 8, 5, 3, 0, 2, 9, 6]
      % % time elapsed: 0.02 s
      % ----------
      % 58941 / 37 = 1593, digit set used (exc w=1) = {2,3,4,5,7,8,9}
      % 7 no. digit variables used, not inc 1
      
      % [a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ]  
      % [3, 7, 5, 9, 3, 5, 8, 9, 4, 2, 8, 5, 3, 4, 3, 3, 3]
      % % time elapsed: 0.02 s
      % ----------
      % ==========
      % Finished in 232msec
      
      
      

      Like

    • elbaz haviv's avatar

      elbaz haviv 1:10 pm on 30 August 2023 Permalink | Reply

      1593 x 37 and 1573 x 37 also fit the puzzle

      Like

      • Jim Randell's avatar

        Jim Randell 1:35 pm on 30 August 2023 Permalink | Reply

        As noted above these 2 candidate solutions are eliminated as they both have 7 different digits erased. The remaining candidate has 8 different erased digits, and so provides the required answer to the puzzle.

        Like

    • elbaz haviv's avatar

      elbaz haviv 4:18 pm on 30 August 2023 Permalink | Reply

      ok later I noticed that but I don’t find
      an edit future to correct my self.
      anyway Thank you.

      Like

  • Unknown's avatar

    Jim Randell 12:16 am on 10 March 2019 Permalink | Reply
    Tags:   

    Teaser 2946: Pentagonal gardens 

    From The Sunday Times, 10th March 2019 [link] [link]

    Adam and Eve have convex pentagonal gardens consisting of a square lawn and paving. Both gardens have more than one right-angled corner. All the sides of the gardens and lawns are the same whole number length in metres, but Adam’s garden has a larger total area. Eve has worked out that the difference in the areas of the gardens multiplied by the sum of the paved areas (both in square metres) is a five-digit number with five different digits.

    What is that number?

    [teaser2946]

     
    • Jim Randell's avatar

      Jim Randell 1:16 am on 10 March 2019 Permalink | Reply

      If I’ve understood this correctly there are only two ways to construct the gardens, and this gives a fairly limited set of integer sides. And only one of those gives a viable 5-digit number.

      I worked out 2 possible shapes for the gardens, where the lawn forms most of the perimeter:

      To make calculating the area easier I have split the lawn of A’s garden in two and inserted the paved area between. The areas are the same as if the lawn was a contiguous square.

      If we suppose the line segments making up the perimeter of the gardens are units, then both squares are unit squares and both triangles have a base of length 1.

      A’s triangle has a height of √(7)/2 and an area of √(7)/4. E’s triangle has a height of √(3)/2 and an area of √(3)/4.

      The difference in the total areas of the gardens is:

      (1 + √(7)/4) − (1 + √(3)/4) = (√7 − √3) / 4

      The sum of the paved areas is:

      √(7)/4 + √(3)/4 = (√7 + √3) / 4

      Multiplying these together we get:

      (√7 + √3) × (√7 − √3) / (4 × 4) = 1 / 4

      So, if the gardens were all of side x, the number N would be:

      N = (x^4) / 4

      For a 5-digit value for N there are only a few values of x to try, and this can be completed manually or programatically.

      This Python program runs in 77ms.

      Run: [ @repl.it ]

      from enigma import (irange, div, is_duplicate, printf)
      
      # consider 5 digit values for N
      for x in irange.round(pow(4 * 10000, 0.25), pow(4 * 99999, 0.25)):
        N = div(pow(x, 4), 4)
        if N is None or is_duplicate(N): continue
        # output solution
        printf("x={x} N={N}")
      

      Solution: The number is 16384.

      Like

      • Jim Randell's avatar

        Jim Randell 8:55 am on 10 March 2019 Permalink | Reply

        I’m pretty sure these are the only two possible shapes.

        If you imagine trying to form a set of 5 equal length linked rods into a convex pentagon with more than one right angle, then it is not possible with 3 right angles, so there must be exactly 2 right angles. And these are either on adjacent vertices or have one vertex between them.

        Either way, the remaining rods are forced into unique positions, giving the shapes A and E.

        Although note that with A there are many ways that a unit square can fit inside the pentagon (not necessarily touching the perimeter).

        Like

  • Unknown's avatar

    Jim Randell 9:30 am on 9 March 2019 Permalink | Reply
    Tags: by: T Verschoyle,   

    Brain-Teaser 462: [Crocodiles] 

    From The Sunday Times, 5th April 1970 [link]

    A friend of mine, who is headmistress of a small school, sends her fifteen girls for a walk every day in a crocodile of threes. She told me that she had for long been trying, unsuccessfully, to arrange that no two girls ever walked together in a trio more than once during a whole week; and she added that, denoting the girls by the first fifteen letters of the alphabet, she wanted A to walk with B and C on Sunday, and with the consecutive pairs of letters for the rest of the week, finishing with N and O on Saturday.

    “Well”, I replied, “if four more trios were specified, I could find a unique solution for your problem. But, if you want to work it out yourself, I shall help you by telling you B’s and C’s partners throughout the week:

    Mon: BHJ, CMN
    Tue: BIK, CLO
    Wed: BLN, CEF
    Thu: BMO, CDG
    Fri: BDF, CIJ
    Sat: BEG, CHK

    Furthermore, F, who is a bit of a snob as regards those lower in the alphabetical order, will be relieved to find that she does not have to walk with the two available furthest from herself in that order until Saturday.

    Now, you should be able to tell me with whom D walks on Sunday and on Wednesday.”

    This puzzle was originally published with no title.

    [teaser462]

     
    • Jim Randell's avatar

      Jim Randell 9:31 am on 9 March 2019 Permalink | Reply

      I’ve marked this puzzle as flawed for two reasons. Firstly when the solution was published it was acknowledged that there was not a unique answer, and secondly I’m not really sure that the constraint about F makes sense.

      My first thought was that it means that F partnered N and O (the two furthest along from F alphabetically) on Saturday, but N and O are already partnering A on Saturday. It does say the “two available furthest from herself”, so perhaps it means F partners L and M (the next furthest alphabetically), but L and M were partnering A on Friday, so can’t appear in a grouping on Saturday. In fact, according to the information we are given, the groups: ANO, BEG, CHK are already defined for Saturday, leaving DFIJLM, to be formed into viable groups. So maybe we are meant to partner F with J and M. This is the interpretation I ended up using, and it does generate the published answer(s). But I think there is still a problem (see below).

      This Python 3 program solves the puzzle recursively in 865ms.

      Run: [ @repl.it ]

      from itertools import combinations
      from enigma import unpack, partitions, join, update, flatten, printf
      
      # check no pairs are repeated
      def pairs(ps, ts):
        ps = ps.copy()
        for t in ts:
          for p in combinations(t, 2):
            if p in ps: return None
            ps.add(p)
        return ps
      
      # complete the groups, with pairs ps already used
      def solve(groups, ps):
        # find days with missing groups
        gs = list((k, vs) for (k, vs) in groups.items() if len(vs) < 5)
        if not gs:
          yield groups
        else:
          # choose the day with the fewest missing groups
          (k, vs) = min(gs, key=unpack(lambda k, vs: 5 - len(vs)))
          # form the remaining kids into groups
          for ts in partitions(kids.difference(*vs), 3):
            ts = list(join(sorted(t)) for t in ts)
            ps2 = pairs(ps, ts)
            if ps2:
              yield from solve(update(groups, [(k, sorted(vs + ts))]), ps2)
      
      # the kids
      kids = set("ABCDEFGHIJKLMNO")
      
      # the groupings we are given
      groups = dict(
        Sun=["ABC"],
        Mon=["ADE", "BHJ", "CMN"],
        Tue=["AFG", "BIK", "CLO"],
        Wed=["AHI", "BLN", "CEF"],
        Thu=["AJK", "BMO", "CDG"],
        Fri=["ALM", "BDF", "CIJ"],
        Sat=["ANO", "BEG", "CHK", "FJM"],
      )
      
      # check no pairing is duplicated among the given groups
      ps = pairs(set(), flatten(groups.values()))
      assert ps
      
      # solve for the remaining groups
      for gs in solve(groups, ps):
        # find the group on day d for child x
        get = lambda d, x: list(t for t in gs[d] if x in t)[0]
        # a measure for F's partners
        fn = lambda d: sum(int(x, 25) - 9 for x in get(d, 'F') if x != 'F')
        # output the groups
        for (k, vs) in gs.items():
          printf("{k}: {vs} [{m}]", vs=join(vs, sep=" "), m=fn(k))
        # D's groups on Sun and Wed
        printf("[D] Sun={S} Wed={W}", S=get("Sun", 'D'), W=get("Wed", 'D'))
        printf()
      

      Solution: There are two possible solutions: (1) D partners H and O on Sunday, and K and M on Wednesday; (2) D partners K and N on Sunday, and J and O on Wednesday.

      The full groupings look like this:

      Sun: ABC DHO EJL FKN GIM
      Mon: ADE BHJ CMN FIO GKL
      Tue: AFG BIK CLO DJN EHM
      Wed: AHI BLN CEF DKM GJO
      Thu: AJK BMO CDG EIN FHL
      Fri: ALM BDF CIJ EKO GHN
      Sat: ANO BEG CHK DIL FJM

      Sun: ABC DKN EIM FHO GJL
      Mon: ADE BHJ CMN FKL GIO
      Tue: AFG BIK CLO DHM EJN
      Wed: AHI BLN CEF DJO GKM
      Thu: AJK BMO CDG EHL FIN
      Fri: ALM BDF CIJ EKO GHN
      Sat: ANO BEG CHK DIL FJM

      And now we run into the problem with F, their “worst” day is suppose to be Saturday, when they partner J and M.

      But in the first case, F partners K and N on Sunday, each of these is one step further along the alphabet than Saturday’s partners, so is surely a less desirable situation. If we just sum the positions in the alphabet of her partners to get a measure of “badness”, the partnering I and O on Monday is also less desirable than Saturday.

      Using the same measure we find that in the second case, Sunday, Monday and Thursday all score as badly as Saturday for F.

      And if we use other measures (e.g. looking for the “best” of the two partners, or the “worst”) we find that in neither of these scenarios does Saturday does provide F with their worst partnering of the week.

      Further, if we consider all possible pairings for F on Saturday (and not a specific one) we find it is not possible to solve the puzzle so F has her worst day on Saturday.

      So maybe it would have just been better to say: “F doesn’t get on with her sisters, J and M. So she will be relieved to find she does not have to walk with them until Saturday”. Or just come straight out with it: “F walked with J and M on Saturday”. But that still leaves the problem of the two answers. Although an extra condition disallowing one of the groupings in one of the answers would sort that out.

      Like

  • Unknown's avatar

    Jim Randell 8:06 am on 8 March 2019 Permalink | Reply
    Tags: ,   

    Teaser 2938: Numerophobia 

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

    In Letterland there are no numerals. They use the decimal system of counting just like we do but the digits 0-9 are represented by the first ten letters of the alphabet AJ inclusive but in no particular order. The following calculations are typical:

    A + G = C
    B × J = FH
    GE × AI = HDB

    What number is represented by ABCDEFGHIJ?

    As stated this puzzle does not have a unique solution.

    This puzzle was not included in the book The Sunday Times Teasers Book 1 (2021).

    [teaser2938]

     
    • Jim Randell's avatar

      Jim Randell 8:07 am on 8 March 2019 Permalink | Reply

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

      This run-file executes in 125ms.

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --answer="ABCDEFGHIJ"
      
      "A + G = C"
      "B * J = FH"
      "GE * AI = HDB"
      

      Solution: There are two solutions: ABCDEFGHIJ = 1840253697, and ABCDEFGHIJ = 3840951627.

      The two solutions arise as we can swap the values of (A, E) with (G, I). One of them is (1, 2) and the other is (3, 9).

      Apparently the setter was unaware that there were two solutions, which seems a bit odd as this kind of puzzle can very easily be checked. For example my own alphametic solver is available here [ https://repl.it/@jim_r/alphametic ]. Click “Run”, enter the expressions, and you get the two solutions straight away. [Note: As of 2024 code sharing via replit no longer works].

      Here’s an example transcript:

      Python 3.6.1 (default, Dec 2015, 13:05:11)
      [GCC 4.8.2] on linux
      expr[0] (or enter) >>> A + G = C
      expr[1] (or enter) >>> B * J = FH
      expr[2] (or enter) >>> GE * AI = HDB
      expr[3] (or enter) >>>
      (A + G = C) (B * J = FH) (GE * AI = HDB)
      (1 + 3 = 4) (8 * 7 = 56) (32 * 19 = 608) / A=1 B=8 C=4 D=0 E=2 F=5 G=3 H=6 I=9 J=7
      (3 + 1 = 4) (8 * 7 = 56) (19 * 32 = 608) / A=3 B=8 C=4 D=0 E=9 F=5 G=1 H=6 I=2 J=7
      [2 solutions]
      [timing] elapsed time: 0.0016964s (1.70ms)
      

      The published solution is:

      Teaser 2938
      There were two possible correct answers: 1840253697 or 3840951627.
      We apologise for any confusion.

      Like

    • GeoffR's avatar

      GeoffR 1:20 pm on 8 March 2019 Permalink | Reply

      % A solution in MinZinc 
      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 /\ G != 0 /\ C != 0 /\ B != 0 
      /\ J != 0 /\ F != 0 /\ H != 0;
      
      constraint all_different ( [A,B,C,D,E,F,G,H,I,J] );
      
      var 10..99: FH = 10*F + H;
      var 10..99: GE = 10*G + E;
      var 10..99: AI = 10*A + I;
      var 100..999: HDB = 100*H + 10*D + B;
      
      constraint A + G == C;
      constraint B * J == FH;
      constraint GE * AI = HDB;
      
      solve satisfy;
      
      output [ "ABCDEFGHIJ = " ++ show(A),show(B),show(C),show(D),show(E),
      show(F),show(G),show(H),show(I),show(J) ];
      
      % ABCDEFGHIJ = 3840951627
      % ABCDEFGHIJ = 1840253697
      
      

      Like

  • Unknown's avatar

    Jim Randell 7:19 am on 7 March 2019 Permalink | Reply
    Tags: by: Dr J A Anderson   

    Brain-Teaser 461: [Grovelball] 

    From The Sunday Times, 29th March 1970 [link]

    The finals of the Ruritanian grovelball championships have just taken place between the four leading teams, each team playing the other three.

    The Archers won the championships, scoring fourteen grovels to one against, while the Bakers scored eight and conceded five.

    The Cobblers, who scored four grovels, conceded the same number as the Donkey-drivers, who failed to score in any of their three games.

    In no game were fewer than three grovels scored, and there were only two games which resulted in the same score.

    What were the scores in the Archers v. Bakers and Archers v. Cobblers games?

    This puzzle was originally published with no title.

    [teaser461]

     
    • Jim Randell's avatar

      Jim Randell 7:22 am on 7 March 2019 Permalink | Reply

      We first note that C and D conceded the same number of goals, say x. And the sum of all the goals scored must be the same as the sum of all the goals conceded:

      14 + 8 + 4 + 0 = 1 + 5 + x + x
      2x = 20
      x = 10

      From there we can use the [[ Football() ]] helper class from the enigma.py library to consider this as a “substituted table” problem. We get a fairly short program, but not especially quick, but it finds the solution in 886ms.

      Run: [ @repl.it ]

      from enigma import Football, digit_map, ordered
      
      # scoring system (all games are played)
      football = Football(games="wdl")
      
      # digits stand for themselves, A=10, E=14
      d = digit_map(0, 14)
      
      # the table (mostly empty)
      (table, gf, ga) = (dict(played="3333", w="???0"), "E840", "15AA")
      
      # consider match outcomes
      for (ms, _) in football.substituted_table(table, d=d):
      
        # find possible scorelines from the goals for/against columns
        for ss in football.substituted_table_goals(gf, ga, ms, d=d):
      
          # additional restrictions:
          # "in no game were fewer than 3 goals scored"
          if any(sum(s) < 3 for s in ss.values()): continue
      
          # "only two games had the same score"
          # so there are 5 different scores involved
          if len(set(ordered(*s) for s in ss.values())) != 5: continue
      
          # output the matches
          football.output_matches(ms, ss, teams="ABCD")
      

      Solution: A vs B = 4-1; A vs C = 7-0.

      There is only one possible set of scorelines:

      A vs B = 4-1
      A vs C = 7-0
      A vs D = 3-0
      B vs C = 3-1
      B vs D = 4-0
      C vs D = 3-0

      So A has 3w, B has 2w+1d, C has 1w, D has 0w.

      Like

  • Unknown's avatar

    Jim Randell 8:16 am on 6 March 2019 Permalink | Reply
    Tags:   

    Teaser 2939: Betting to win 

    From The Sunday Times, 20th January 2019 [link] [link]

    Two teams, A and B, play each other.

    A bookmaker was giving odds of 8-5 on a win for team A, 6-5 on a win for team B and X-Y for a draw (odds of X-Y mean that if £Y is bet and the bet is successful then £(X + Y) is returned to the punter). I don’t remember the values of X and Y, but I know that they were whole numbers less than 20.

    Unusually, the bookmaker miscalculated! I found that I was able to make bets of whole numbers of pounds on all three results and guarantee a profit of precisely 1 pound.

    What were the odds for a draw, and how much did I bet on that result?

    [teaser2939]

     
    • Jim Randell's avatar

      Jim Randell 8:17 am on 6 March 2019 Permalink | Reply

      If the integer stakes are p for A to win, q for B to win, r for a draw, we have:

      (13/5)p = p + q + r + 1
      (11/5)q = p + q + r + 1
      ((X + Y)/Y)r = p + q + r + 1

      which, given X and Y, we can solve as:

      p = 55(X + Y) / (23X – 120Y)
      q = 65(X + Y) / (23X – 120Y)
      r = 143Y / (23X – 120Y)

      and we want these to be integers.

      X and Y are limited to be integers between 1 and 19, so we can easily check all possibilities.

      This Python program runs in 72ms.

      Run: [ @repl.it ]

      from itertools import product
      from enigma import (irange, printf)
      
      # consider possible values for X, Y
      for (X, Y) in product(irange(1, 19), repeat=2):
        # calculate integer stakes:
        # p (for A to win)
        # q (for B to win)
        # r (for a draw)
        d = 23 * X - 120 * Y
        if not (d > 0): continue
        (p, x) = divmod(55 * (X + Y), d)
        if x != 0: continue
        (q, x) = divmod(65 * (X + Y), d)
        if x != 0: continue
        (r, x) = divmod(143 * Y, d)
        if x != 0: continue
      
        # output solution
        printf("X={X} Y={Y}, p={p} q={q} r={r}")
      
        # verify the winnings
        w = p + q + r + 1
        assert divmod(13 * p, 5) == (w, 0)
        assert divmod(11 * q, 5) == (w, 0)
        assert divmod((X + Y) * r, Y) == (w, 0)
      

      Solution: The odds for a draw were 11-2. The bet on a draw was £22.

      A variation: If the bets can be whole numbers of pennies, instead of whole numbers of pounds, then there is another solution where X-Y is 10-1 and the bets are £5.50 on A to win, £6.50 for B to win, £1.30 on a draw. The winnings are £14.30 for a total outlay of £13.30.

      Like

    • GeoffR's avatar

      GeoffR 8:22 am on 7 March 2019 Permalink | Reply

      % A solution in MinZinc 
      var 1..19: X; var 1..19: Y;
      
      % Integer stakes are p for A to win, q for B to win, and r for a draw
      % For bets of p, q and r, a return of (p + q + r + 1) makes a profit of £1
      var 1..100: p; var 1..100: q; var 1..100: r;
      
      constraint 13 * p = (p + q + r + 1) * 5;        % 8-5 odds for team A
      constraint 11 * q = (p + q + r + 1) * 5;        % 6-5 odds for team B
      constraint (X + Y )* r = (p + q + r + 1) * Y;   % X-Y odds for a draw
      
      solve satisfy;
      
      % X = 11; Y = 2; p = 55; q = 65; r = 22;
      % ==========
      % Finished in 195msec 
      % Odds for a draw were 11/2 and the stake for a draw was £22
      
      

      Like

  • Unknown's avatar

    Jim Randell 11:16 am on 5 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 460: [Crates of Boppo] 

    From The Sunday Times, 22nd March 1970 [link]

    Boppo is made up in 1 lb cans at 8s, 2 lb cans at 15s and 4 lb cans at 27s. The contents of crates vary, but every crate contains 60 cans of mixed three sizes with a total value of £45.

    The foreman himself had packed two such crates. He told new worker Rob, “Just go along and nail down those two open crates in the shed, Rob. The lorry’s waiting.”

    Rob found the two crates standing beside the weighing platform, and for no particular reason he weighed them. One was heavier than the other. “Huh! Calls ‘isself a foreman” he said, as he removed some cans from the heavier crate. “That’s it. Both the same now. Lucky I weighed ’em”. So he nailed them down and the lorry went off with them.

    He met the foreman. “You made a mistake with those crates, chum”, he said, “but it’s OK now. Here’s three spare cans.”

    “!!” said the foreman.

    What were the weights of the two crates the foreman had packed?

    This puzzle was originally published with no title.

    [teaser460]

     
    • Jim Randell's avatar

      Jim Randell 11:19 am on 5 March 2019 Permalink | Reply

      Before decimalisation £1 was the same as 20 shillings, so each crate has a monetary value of 900 shillings.

      I solved this using a similar approach to Enigma 486 (and borrowed some of the code too).

      This Python 3 program runs in 108ms.

      from enigma import (defaultdict, irange, subsets, printf)
      
      # express total <t> using denominations <ds>, min quantity 1
      def express(t, ds, s=[]):
        if not ds:
          if t == 0:
            yield s
        else:
          (d, *ds) = ds
          for i in irange(1, t // d):
            yield from express(t - d * i, ds, s + [i])
      
      # the weights and costs of the cans
      weights = (1, 2, 4)
      costs = (8, 15, 27)
      
      # find ways to split the cost of a crate into cans
      crates = defaultdict(list)
      for ns in express(900, costs):
        # but each crate has 60 cans
        if not (sum(ns) == 60): continue
        # calculate the total weight of the crate
        t = sum(n * w for (n, w) in zip(ns, weights))
        printf("[{ns} -> weight = {t}]")
        crates[t].append(ns)
      
      # possible weights of 3 cans to be removed
      w3s = defaultdict(list)
      for rs in subsets(weights, size=3, select='R'):
        w3s[sum(rs)].append(rs)
      
      # find two crates with weights that differ by 3 cans
      for (w1, w2) in subsets(sorted(crates.keys()), size=2):
        for rs in w3s[w2 - w1]:
          # check there are enough cans in the w2 crate
          if not any(all(not (r > n) for (r, n) in zip(rs, ns)) for ns in crates[w2]): continue
          # output solution
          printf("{w2} lb -> {w1} lb by removing {rs} x {weights} lb cans")
      

      Solution: The crates the foreman had packed weighed 122 lb and 126 lb.

      Rob reduced the weight of the 126 lb crate to 122 lb by removing 2× 1 lb cans and 1× 2 lb can.

      There are only 3 ways to pack the crates so they have 60 cans and are worth 900 shillings (900s) (where the is at least 1 of each type of can included):

      12× 1 lb @ 8s + 41× 2 lb @ 15s + 7× 4 lb @ 27s = 60 cans, 122 lb, 900s
      24× 1 lb @ 8s + 22× 2 lb @ 15s + 14× 4 lb @ 27s = 60 cans, 124 lb, 900s
      36× 1 lb @ 8s + 3× 2 lb @ 15s + 21× 4 lb @ 27s = 60 cans, 126 lb, 900s

      If we don’t require that all three weights of can are represented in the crate then we can make a crate with 60× 2 lb cans, which weighs 120 lb, and gives rise to multiple solutions.

      Like

    • GeoffR's avatar

      GeoffR 7:42 am on 6 March 2019 Permalink | Reply

      The only 3 ways to pack a crate are found in my MiniZinc programme as 122 lb, 124 lb and 126 lb

      The only way of removing 3 cans to make the crates equal is to remove 3 cans ( 2 of 1lb and 1 of 2lb = 4lb) to reduce the crate weighing 126 ilb to 122 lb.

      Therefore, the foreman had packed 122 lb and 126 lb into the two crates.

      var 1..60: n1; var 1..60: n2;  var 1..60: n3;   % Numbers of  three types of can
      var 1..200: wt;   %total weight of all cans in 1 crate
      
      constraint n1 + n2 + n3 == 60;  % Every crate contains 60 cans
      constraint n1 * 8 + n2 * 15 + n3 * 27 == 900;   %sh £45 * 20 = 900 shillings for 1 crate
      constraint wt = n1 * 1 + n2 * 2 + n3 * 4;
      
      solve satisfy;
      
      % n1 = 12;  n2 = 41;  n3 = 7;  wt = 122;
      %----------
      % n1 = 24;  n2 = 22;  n3 = 14;  wt = 124;
      % ----------
      % n1 = 36;  n2 = 3;  n3 = 21;  wt = 126;
      %----------
      %==========
      %Finished in 199msec
      
      

      Like

  • Unknown's avatar

    Jim Randell 9:32 am on 4 March 2019 Permalink | Reply
    Tags: by: Arithmedicus,   

    Brain-Teaser 459: [Grandchildren] 

    From The Sunday Times, 8th March 1970 [link]

    Grandpa was as pleased as Punch when he heard that his large flock of grandchildren would be there at his birthday party, but he couldn’t remember how many there were. So he wrote to his youngest daughter, who knew he liked problems, and got back the answer:

    “There are just enough children to arrange them in pairs in such a way that the square of the age of the first of a pair added to thrice the square of the age of the second give the same total for every pair. The eldest is still a teenager. You remember that I have twins one year old.”

    How many grandchildren are there?

    This puzzle was originally published with no title.

    [teaser459]

     
    • Jim Randell's avatar

      Jim Randell 9:33 am on 4 March 2019 Permalink | Reply

      I think the wording of this puzzle could be improved. Saying there are “just enough” children sounds like we are looking for the minimum number of children to satisfy the conditions, given that there are two ages of 1 amongst the children, and one teenager. So we already have three values that must be used in the pairs. The smallest potential set would be two pairs, and this is achievable, giving an answer of 4 children.

      But it appears this is not the solution the setter had in mind. Instead it seems we want the largest possible number of children that can be formed into different pairs that give the same value for the function. If we were to allow duplicate pairs (i.e. pairs of children with the same ages in the same order), then we could increase the number of children to be as large as we want.

      Instead this program looks to group the ages of pairs of children into sets that give the same value for the function. We then need a set that has two 1’s and also value between 13 and 19. Then we look for the maximum number of different pairs of children possible, and this is the answer that was published.

      This Python program runs in 81ms.

      Run: [ @repl.it ]

      from enigma import (defaultdict, irange, subsets, printf)
      
      ages = set(irange(1, 19))
      
      # record the pairs by total
      d = defaultdict(list)
      
      # consider pairs of ages
      for (a, b) in subsets(ages, size=2, select='M'):
        n = a**2 + 3 * b**2
        d[n].append((a, b))
      
      # consider the values found
      for k in sorted(d.keys()):
        ps = d[k]
        # look for pairs where 1 occurs twice
        if not (sum(p.count(1) for p in ps) == 2): continue
        # and the eldest is a teenager
        if not (max(max(p) for p in ps) > 12): continue
        # output solution
        printf("{k} -> {ps}")
      

      Solution: There are 12 grandchildren.

      It turns out there is only one possible total that gives a viable set of pairs. The pairs are:

      (1, 11) (8, 10) (11, 9) (16, 6) (17, 5) (19, 1)

      Each giving the value of 364 when the function f(a, b) = a^2 + 3b^2 is applied to them.

      So there two 1 year olds (the twins) and also two 11 year olds.

      If we had four children of ages 1, 1, 11, 19, we would have “just enough” to form them into 2 pairs – (1, 11) and (19, 1) – that give the same value under the function, and there are two 1’s and a teenager involved. So this would be the answer if we take a strict interpretation of the wording.

      Similarly, if we allow duplication among the pairs we could have 14 children, or 16, etc.

      Like

      • Jim Randell's avatar

        Jim Randell 10:07 am on 4 March 2019 Permalink | Reply

        A variation would be to look for the largest number of children of different ages (apart from the twins) that can form the pairs.

        In this case we would have to discard the (11, 9) pair to leave:

        (1, 11) (8, 10) (16, 6) (17, 5) (19, 1)

        So there would be 10 children.

        Like

  • Unknown's avatar

    Jim Randell 7:12 am on 3 March 2019 Permalink | Reply
    Tags: ,   

    Teaser 2940: Getting there in the end 

    From The Sunday Times, 27th January 2019 [link]

    A tractor is ploughing a furrow in a straight line. It starts from rest and accelerates at a constant rate, taking a two-digit number of minutes to reach its maximum speed of a two-digit number of metres per minute. It has, so far, covered a three-digit number of metres. It now maintains that maximum speed for a further single-digit number of minutes and covers a further two-digit number of metres. It then decelerates to rest at the same rate as the acceleration. I have thus far mentioned ten digits and all of them are different.

    What is the total distance covered?

    As stated this puzzle does not have a unique solution.

    This puzzle was not included in the book The Sunday Times Teasers Book 1 (2021).

    [teaser2940]

     
    • Jim Randell's avatar

      Jim Randell 7:12 am on 3 March 2019 Permalink | Reply

      The tractor starts at rest:

      u = 0

      It then accelerates, at constant rate a, in time t1, to velocity v:

      v = a.t1
      a = v/t1

      During this period it has covered a distance d1:

      d1 = (1/2)a(t1^2) = v.t1/2

      It continues at a constant velocity v, for time t2, and covers distance d2:

      d2 = v.t2

      It then decelerates to rest, at a rate of −a, covering distance d1 again.

      The required answer being:

      d1 + d2 + d1 = v(t1 + t2)

      We can consider the alphametic expressions where:

      t1 = AB; v = CD; d1 = EFG; t2 = H; d2 = IJ

      This can be easily solved by the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      This run-file executes in 126ms.

      Run: [ @repl.it ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --answer="2 * EFG + IJ"
      
      "div(AB * CD, 2) = EFG"
      "CD * H = IJ"
      

      Solution: There are three possible total distances: 646m, 864m, 1316m.

      None of the solutions are particularly realistic. Each of them involve the tractor accelerating incredibly slowly for a very long time to reach an extremely modest top speed, and later take just as long to decelerate. Perhaps with a change of units the problem could made to apply to something that does take a long time to decelerate, like a train, oil tanker or spaceship.

      It would also have been easy to require just one of the possible answers, maybe by specifying the answer has 4 digits (1316m), or that all the digits are different (864m).


      The published solution is:

      Teaser 2940
      There were three possible correct answers.
      646, 864 or 1316m. We apologise for any confusion.

      Like

  • Unknown's avatar

    Jim Randell 8:54 am on 2 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 458: [Football tournament] 

    From The Sunday Times, 1st March 1970 [link]

    The table gives the results of an all-play-all soccer tournament is South America.

    If I tell you the number of scores of one goal by either side in the 3 games played by Brazil you can deduce the scores of the games between Argentine and Peru and Argentine and Ecuador.

    What are they?

    This puzzle was originally published with no title.

    [teaser458]

     
    • Jim Randell's avatar

      Jim Randell 8:55 am on 2 March 2019 Permalink | Reply

      The enigma.py library includes the [[ Football() ]] class to help in solving puzzles involving football tables, and the [[ filter_unique() ]] function to help in solving puzzles of the form “… if I told you this, then you could work out that…”. We can use both of these to solve this puzzle.

      This Python program runs in 98ms.

      Run: [ @repl.it ]

      from enigma import Football, filter_unique, unpack
      
      # record possible outcomes
      rs = list()
      
      # scoring system
      football = Football(games='wdl')
      
      # the order of the teams in the table
      (B, A, P, E) = (0, 1, 2, 3)
      
      # digits in the table stand for themselves
      d = dict((x, int(x)) for x in "01234789")
      
      # the columns of the table
      (table, gf, ga) = (dict(w="3100", d="0121", l="0112"), "9724", "3847")
      
      # find possible match outcomes
      for (ms, _) in football.substituted_table(table, d=d):
      
        # find possible scorelines using the goals for/against columns
        for ss in football.substituted_table_goals(gf, ga, ms, d=d):
      
          # record outcomes
          rs.append((ms, ss))
      
      # if I told you...
      # the number of scores of 1 goal by either side in the games played by B...
      f = unpack(lambda ms, ss: sum(v.count(1) for (k, v) in ss.items() if B in k))
      
      # you can deduce the scores in the AvP and AvE match
      g = unpack(lambda ms, ss: (ss[(A, P)], ss[(A, E)]))
      
      # find the unique solutions
      (rs, _) = filter_unique(rs, f, g)
      
      # output solutions
      for (ms, ss) in rs:
        football.output_matches(ms, ss, "BAPE")
      

      Solution: A vs P = 1-1. A vs E = 5-3.

      The scores in all matches are uniquely determined. They are:

      B vs A = 4-1
      B vs P = 3-1
      B vs E = 2-1
      A vs P = 1-1
      A vs E = 5-3
      P vs E = 0-0

      Like

  • Unknown's avatar

    Jim Randell 12:31 pm on 1 March 2019 Permalink | Reply
    Tags:   

    Teaser 2941: Big deal 

    From The Sunday Times, 3rd February 2019 [link] [link]

    My wife and I play bridge with Richard and Linda. The 52 cards are shared equally among the four of us – the order of cards within each player’s hand is irrelevant but it does matter which player gets which cards. Recently, seated in our fixed order around the table, we were discussing the number of different combinations of cards possible and we calculated that it is more than the number of seconds since the “big bang”!

    We also play another similar game with them, using a special pack with fewer cards than in the standard pack – again with each player getting a quarter of the cards. Linda calculated the number of possible combinations of the cards for this game and she noticed that it was equal to the number of seconds in a whole number of days.

    How many cards are there in our special pack?

    [teaser2941]

     
    • Jim Randell's avatar

      Jim Randell 12:32 pm on 1 March 2019 Permalink | Reply

      If there are k players, and each player receives n cards in the deal, then there are n.k cards in total.

      The number of ways of dealing n cards to the first player from the total set of n.k cards are:

      C(n.k, n) = (n.k)! / [ n! (n(k − 1))! ]

      For the second player there are only n(k − 1) cards remaining, and dealing n cards from that we get:

      C(n(k − 1), n) = (n(k − 1))! / [ n! (n(k − 2))! ]

      For the third player:

      C(n(k − 2), n) = (n(k − 2))! / [ n! (n(k − 3))! ]

      and so on up to the final player

      C(n, n) = n! / [ n! 0! ] = 1

      Multiplying all these together we find that one of the terms in the denominator cancels with the numerator for the next player, giving a total number of possible deals of:

      deals(k, n) = (n.k)! / (n!)^k

      We can use this rather neat formula to find the required number of cards in the puzzle.

      This Python program runs in 74ms.

      from enigma import (irange, inf, factorial, arg, printf)
      
      # number of players
      k = arg(4, 0, int, prompt="number of players")
      
      # multiple = number of seconds in a day (assumed constant)
      m = arg(60 * 60 * 24, 1, int, prompt="multiple")
      
      printf("[{k} players, m = {m}]")
      
      # number of cards per player
      for n in irange(1, inf):
        p = factorial(n * k) // pow(factorial(n), k)
        (d, r) = divmod(p, m)
        printf("{t} cards, {n} each, {p} deals, {d} days (+ {r}s)", t=n * k)
        if r == 0: break
      

      Solution: There are 28 cards in the special pack.

      Like

  • Unknown's avatar

    Jim Randell 2:05 pm on 28 February 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 457: [March-past] 

    From The Sunday Times, 15th February 1970 [link]

    The Duke of Teresa and Baron von Barin agreed to have a march-past of their respective men-at-arms to celebrate the wedding of the Duke’s son with Baron’s daughter. Each troop would march past in column of three (i.e. 3 men per file). The Duke has a few thousand men and the Baron about half as many.

    On the appointed day however, one of the Duke’s men could not go on parade and so the men were ordered into column of four, but 3 men were left over, whereupon they formed column of five and 4 men were left over, and this pattern of behaviour persisted as the Duke consecutively increased the number per file until all the men made an exact number of files.

    Meanwhile, the Baron has the same problem. One man reported sick and he consecutively increased the number per file and in column of four had 3 left over, column of five had 4 left over, etc., and eventually he reached a number per file that left no man spare.

    The Baron’s men proceeded to march past but the Duke was in a dilemma as each body of troops had a different number of men per file. He immediately solved this by ordering his men to form files with the same number of men as the Baron’s. This they did without any men being left over.

    How many men respectively had the Duke and the Baron on parade?

    This puzzle was originally published with no title.

    [teaser457]

     
    • Jim Randell's avatar

      Jim Randell 2:09 pm on 28 February 2019 Permalink | Reply

      The total number of men (including the indisposed man) must be able to form 3, 4, 5, … lines, if they are unable to form lines when one of them is missing, being short by one man.

      So, if we can form 3, 4, 5, … lines, the total number of men must be a multiple of 3, 4, 5, …, i.e. a multiple of lcm(3, 4, 5, …).

      This Python program looks for possible total numbers of men for the Duke D and the Baron B, and then finds the solution where the ratio D/B is closest to 2. I assumed the Duke had somewhere between 2,000 and 10,000 men. The program runs in 84ms.

      Run: [ @repl.it ]

      from itertools import count, combinations
      from collections import defaultdict
      from enigma import irange, mlcm, fdiv, Accumulator, printf
      
      # suppose the number of men (n - 1) end dividing into k equal sized lines (k > 6)
      # for all lowers numbers they are one short, so n must be a multiple of all lower numbers
      
      # minimum/maximum numbers to consider for D
      (m, M) = (2000, 10000)
      
      # record lcms up to M by k
      d = defaultdict(list)
      for k in count(7):
        n = mlcm(*irange(2, k - 1))
        if n > M: break
        d[k] = n
      
      # choose the result with D/B nearest to 2.0
      r = Accumulator(fn=(lambda x, y: (x if abs(x - 2.0) < abs(y - 2.0) else y)))
      
      # choose k's for D and B (kD < kB)
      for (kD, kB) in combinations(sorted(d.keys()), 2):
        (mD, mB) = (d[kD], d[kB])
        # the Duke has "a few thousand men"
        for D in irange(mD, M, step=mD):
          if D < m: continue
          # (D - 1) is divisible by kD and kB
          if not ((D - 1) % kD == 0 and (D - 1) % kB == 0): continue
          # the Baron "about half as many"
          for B in irange(mB, M, step=mB):
            # (B - 1) is divisible by kB
            if (B - 1) % kB != 0: continue
      
            # output the solution (the numbers on parade are B-1, D-1)
            r.accumulate_data(fdiv(D, B), (D - 1, B - 1))
            printf("kD={kD} kB={kB}, mD={mD} mB={mB}, D={D} B={B} [D/B ~ {f:.3f}]", f=fdiv(D, B))
      
      # output the solution
      (D, B) = r.data
      printf("parade: B={B}, D={D}")
      

      Solution: The Duke had 5159 men on parade. The Baron had 2519 men on parade.

      The ratio D/B is approximately 2.05.

      The Duke’s men are one man short of forming 3, 4, 5, 6 lines, but can form 7 lines (5159 = 737 × 7).

      The Baron’s men are one man short of forming 3, 4, 5, 6, 7, 8, 9, 10 lines, but can form 11 lines (2519 = 229 × 11).

      The Duke’s men can also form 11 lines (5159 = 469 × 11).

      There is a further solution where the Duke has 9779 men on parade (and the Baron still has 2519), but in this case the D/B ratio is 3.88.

      If we allow the Duke and the Baron more men then we can get the ratio closer to 2. There is a solution with D=60599 and B=30239, giving a ratio of 2.004, but it is hard to describe 60,600 men as “a few thousand”.

      Like

  • Unknown's avatar

    Jim Randell 1:55 pm on 27 February 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 456: [Chess competition] 

    From The Sunday Times, 8th February 1970 [link]

    The organiser of our lightning chess competition works on a strict timetable; he allows ten minutes a match, and makes no concession, in his planning, for draws or protracted games.

    Last year having five chess boards available for use, he arranged an American tournament (in which every competitor played one match against every other player). This year there would be exactly twice as many competitors as last year if one man hadn’t recently dropped out; and only one chessboard is available.

    He is therefore organising a knock-out competition: and he reports that his total time allocation will be precisely the same this year as it was last year.

    How many competitors are there this year?

    This puzzle was originally published with no title.

    [teaser456]

     
    • Jim Randell's avatar

      Jim Randell 1:56 pm on 27 February 2019 Permalink | Reply

      For n players there are T(n − 1) = n(n − 1)/2 matches in a tournament where every player plays every other player.

      So, with 5 simultaneous matches this would mean the number of allocated time slots would be:

      T = n(n − 1)/10

      In a knockout competition with m players there are (m − 1) games. (One player is eliminated in each game, until there is just one player left).

      So with only one match going on at a time, the total number of allocated time slots would be:

      T = m − 1

      And we are told that the number in the knockout tournament is m = 2n − 1.

      So, equating the times:

      m − 1 = n(n − 1)/10
      10(2n − 2) = n(n − 1)
      20(n − 1) = n(n − 1)
      n = 20 (as n ≠ 1)

      So last year there were 20 competitors. This year there are 39.

      Solution: This year there are 39 competitors.

      Liked by 1 person

  • Unknown's avatar

    Jim Randell 10:07 am on 26 February 2019 Permalink | Reply
    Tags: ,   

    Brain-Teaser 455: [Darts teams] 

    From The Sunday Times, 1st February 1970 [link]

    Every week we field a village darts team of 3 men, one from each of our pubs (Plough, Queen’s Head, and Roebuck). Altogether we can call on 14 players (whose names, luckily, start respectively with the first 14 letters of the alphabet): five of them frequent the Plough, six the Queen’s Head and seven the Roebuck, the apparent discrepancy is explained by the thirsts of Ernie, Fred, Len and Mark, all of whom are “two-pub men” and are thus eligible to represent either of their haunts.

    For over three years we have picked a different team each week and have just exhausted all 162 possible combinations. The last two teams were:

    Joe, Nigel, Charlie
    Charlie, Fred, Harry

    For the next seven weeks we are waiving the one-man-per-pub rule and have picked teams which have not so far played together. The are:

    Ernie, Len, Mark
    Ian, Fred, Alan
    Joe, Fred, George
    Len, Mark, Keith
    Fred, Keith, Nigel
    Ernie, Len, Nigel
    Ian, Joe, and one other to be picked from a hat on the night.

    Which darts players frequent the Roebuck?

    This puzzle was originally published with no title.

    [teaser455]

     
    • Jim Randell's avatar

      Jim Randell 10:07 am on 26 February 2019 Permalink | Reply

      I found two solutions for this puzzle, although with a slight change in the wording we could arrive at a unique solution.

      This Python program runs in 226ms.

      Run: [ @repl.it ]

      from itertools import product, permutations, combinations
      from enigma import icount, unpack, printf
      
      # all the players
      players = "ABCDEFGHIJKLMN"
      
      # players with dual allegiance
      duals = "EFLM"
      
      # the pubs
      pubs = set("PQR")
      
      # do the three sets form a team
      def team(a, b, c):
        for (x, y, z) in permutations(pubs):
          if x in a and y in b and z in c: return True
        return False
      
      # choose the "missing" pub for the duals
      for s1 in product(pubs, repeat=4):
        (E, F, L, M) = (pubs.difference([x]) for x in s1)
      
        # ELM do not form a team
        if team(E, L, M): continue
      
        # choose (single) pubs for K, N
        for s2 in product(pubs, repeat=2):
          (K, N) = (set([x]) for x in s2)
      
          # KLM, FKN, ELN do not form teams
          if team(K, L, M) or team(F, K, N) or team(E, L, N): continue
      
          # CJN do form a team
          for s3 in permutations(pubs.difference(N)):
            (C, J) = (set([x]) for x in s3)
      
            # remaining assignments for given combinations, AGHI
            for s4 in product(pubs, repeat=4):
              (A, G, H, I) = (set([x]) for x in s4)
      
              # check the remaining combinations
              if not (team(C, F, H)) or team(A, F, I) or team(F, G, J): continue
      
              # which leaves B and D
              for s5 in product(pubs, repeat=2):
                (B, D) = (set([x]) for x in s5)
      
                table = (A, B, C, D, E, F, G, H, I, J, K, L, M, N)
      
                # P, Q, R should have teams of 5, 6, 7
                (P, Q, R) = (icount(table, (lambda x: p in x)) for p in 'PQR')
                if (P, Q, R) != (5, 6, 7): continue
      
                # count the total possible teams
                t = icount(combinations(table, 3), unpack(team))
                # there should be 162
                if t != 162: continue
      
                # find how many unused IJ? combinations there are
                ijs = list(p for (p, x) in zip(players, table) if p not in 'IJ' and not team(I, J, x))
                # there should be at least 2
                if len(ijs) < 2: continue
      
                # who plays for R
                Rs = list(p for (p, x) in zip(players, table) if 'R' in x)
      
                printf("Rs = {Rs}")
                printf("  A={A} B={B} C={C} D={D} E={E} F={F} G={G} H={H} I={I} J={J} K={K} L={L} M={M} N={N}")
                printf("  ijs={ijs}")
                printf()
      

      Solution: A, B, D, F, G, I, J are on the Roebuck team.

      This solution assumes that the final team member of the I+J+? team that is picked out of the hat can be any of the other players (i.e. I and J have never played together on a team before).

      The team allegiances in this case are:

      P = C, E, F, L, M [5]
      Q = E, H, K, L, M, N [6]
      R = A, B, D, F, G, I, J [7]

      However, I took the construction of final I+J+? team by picking a name out of a hat to require only that there should be more than one candidate to placed in the hat. If we have the following team allegiances:

      P = E, F, J, L, M [5]
      Q = E, H, K, L, M, N [6]
      R = A, B, C, D, F, G, I [7]

      Then this is also a solution to the puzzle. In this case the remaining possible partners for I+J+? are: A, B, C, D, F, G.

      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
Design a site like this with WordPress.com
Get started