Updates from August, 2020 Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 8:45 am on 30 August 2020 Permalink | Reply
    Tags: ,   

    Teaser 1858: Cash flow 

    From The Sunday Times, 26th April 1998 [link]

    We play a variation of a famous puzzle game using coins instead of rings. We start with a pile of coins consisting of at least one of each of the 1p, 2p, 5p, 10p, 20p, 50p and £1 coins, with no coin on top of another that is smaller in diameter. So the 5p coins are on the top, then the 1p, 20p, £1, 10p, 2p and 50p coins respectively, with the 50p coins being on the bottom. One typical pile is illustrated:

    The object of the game is to move the pile to a new position one coin at a time. At any stage there can be up to three piles (in the original position, the final position, and one other). But in no pile can any coin ever be above another of smaller diameter.

    We did this with a pile of coins recently and we found that the minimum number of moves needed equalled the value of the pile in pence. We then doubled the number of coins by adding some 1p, 5p and 50p coins totalling less than £3, and we repeated the game. Again the minimum number of moves equalled the value of the new pile in pence.

    How many coins were in the pile for the first game?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1852]

     
    • Jim Randell's avatar

      Jim Randell 8:46 am on 30 August 2020 Permalink | Reply

      (See also: Enigma 1254, Enigma 14).

      In a standard Towers of Hanoi problem there are n discs of different sizes.

      In the optimal solution the largest disc is moved 1 time, the next largest 2 times, then 4 times, 8 times, 16 times, …

      So we get a total number of moves: H(n) = 2^n − 1.

      In this version there are multiple discs the same size, but we can treat a block of k discs the same size as a single disk that requires k moves, and solve the puzzle in the same way.

      So, the stack shown in the diagram (which I denote (1, 2, 1, 1, 3, 1, 1), by counting the number of coins of each size, starting at the bottom), will require: 1×1 + 2×2 + 1×4 + 1×8 + 3×16 + 1×32 + 1×64 = 161 moves.

      In general if there number of coins of each size is (A, B, C, D, E, F, G) then the number of moves is:

      A + 2B + 4C + 8D + 16E + 32F + 64G

      and the monetary value of the coins is:

      50A + 2B + 10C + 100D + 20E + F + 5G

      and if these values are equal, we get:

      49A + 6C + 92D + 4E = 31F + 59G

      In the puzzle, the number of coins is doubled by increasing A by a, F by f, G by g, and their monetary value is less than £3:

      50a + f + 5g < 300

      but the monetary value of the augmented stack is still equal to the number of moves required, so:

      49a = 31f + 59g

      We can work out possible values for a, f, g, and their sum gives us the initial number of coins (which is the answer to the puzzle).

      We can then look for stacks of coins of this size with the monetary value and number of moves, and then add the extra coins to the stack and see if the condition still holds.

      This Python 3 program runs in 54ms.

      Run: [ @replit ]

      from enigma import (irange, div, printf)
      
      # denominations of coins by size (largest diameter to smallest diameter)
      ds = (50, 2, 10, 100, 20, 1, 5)
      
      # number of moves for sequence of discs (largest to smallest)
      def H(ns):
        t = 0
        m = 1
        for n in ns:
          t += m * n
          m *= 2
        return t
      
      # decompose <t> into <k> positive numbers
      def decompose(t, k, s=[]):
        if k == 1:
          yield s + [t]
        else:
          for x in irange(1, t + 1 - k):
            yield from decompose(t - x, k - 1, s + [x])
      
      # choose a value for a (= 50p, so there must be 1-5)
      for a in irange(1, 5):
        # choose a value for g (= 5p)
        for g in irange(1, (299 - 50 * a) // 5):
          # calculate f
          f = div(49 * a - 59 * g, 31)
          if f is None or f < 1 or not(50 * a + 5 * g + f < 300): continue
          # the total number of extra coins = the number of original coins
          n = a + f + g
          # output solution
          printf("n={n} [a={a} f={f} g={g}]")
      
          # allocate the number of original coins (n in total)
          for ns in decompose(n, 7):
            # calculate the total value of the stack
            t = sum(n * d for (n, d) in zip(ns, ds))
            # calculate the number of moves for the stack
            m = H(ns)
            if m != t: continue
      
            # make the final stack
            ns2 = list(ns)
            ns2[0] += a
            ns2[5] += f
            ns2[6] += g
            # calculate the total value of the stack
            t2 = sum(n * d for (n, d) in zip(ns2, ds))
      
            # output solution
            printf("-> {ns} [{t}] -> {ns2} [{t2}]")
      

      Solution: There were 12 coins in the original pile.

      There is only one possible size for the original pile, and it must be composed of: (2× 50p, 1× 2p, 1× 10p, 1× £1, 3× 20p, 1× 1p, 3× 5p), making a total value of 288p and requiring 288 moves.

      We then add: (5× 50p, 6× 1p, 1× 5p) = 261p to make a pile with total value 549p and requiring 549 moves.

      Like

  • Unknown's avatar

    Jim Randell 9:26 am on 16 August 2020 Permalink | Reply
    Tags: by: PL Havard   

    Teaser 1852: Fits to a T 

    From The Sunday Times, 15th March 1998 [link]

    We wish to just completely cover a 6-by-6 square grid with T-shaped pieces made up of 4 squares as shown. No overlapping is allowed. We wish to do this in as many different ways as possible. Any pattern that can be obtained from another by rotation or reflection is regarded as the same pattern.

     

    (a) In how many ways can the 6-by-6 grid be filled?
    (b) In how many ways can a 10-by-10 grid be filled?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1852]

     
    • Jim Randell's avatar

      Jim Randell 9:27 am on 16 August 2020 Permalink | Reply

      Each T-shaped piece consists of 4 smaller squares, so to tile an n×n grid we require n² to be divisible by 4 (i.e. n to be divisible by 2).

      For a 6×6 grid we would need 9 T’s, and for a 10×10 grid we would need 25 T’s.

      If we colour the grid chessboard-style with alternating black and white squares, then we see when we place a T it will cover either 3 black + 1 white (type A), or 3 white + 1 black (type B).

      So, for an n×n grid, if we choose k type A shapes (for k = 0..(n²/4)) we will need ((n²/4) − k) type B shapes to give the required number of squares.

      And we need the number of black squares and the number of white squares to both be n²/2:

      3k + ((n²/4) − k) = n²/2
      2k = n²/4
      k = n²/8

      So n² must be divisible by 8, and hence n must be divisible by 4.

      Therefore we cannot tile a 6×6 grid or a 10×10 grid using T4 shapes.

      Solution: There are no ways to fill either the 6×6 grid or the 10×10 grid.

      But we can tile a (4n)×(4n) grid by repeating the following pattern:

      Like

  • Unknown's avatar

    Jim Randell 11:43 am on 11 August 2020 Permalink | Reply
    Tags:   

    Brainteaser 1839: It’s a knockout 

    From The Sunday Times, 14th December 1997 [link]

    Sixteen teams, A-P, entered a knockout football competition. In none of the matches did any team score more than five goals, no two matches had the same score, and extra time ensured that there were no draws.

    The table shows the total goals, for and against, for each team:

    My own team, K, was knocked out by the team who were the eventual champions.

    Who played whom in the semi-finals, and what were the scores.

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1839]

     
    • Jim Randell's avatar

      Jim Randell 11:44 am on 11 August 2020 Permalink | Reply

      When we look at the table we can spot teams that might have been knocked out in the first round. The number of goals for and against must be different (no draws) and neither must be more than 5. We can then choose 8 such teams, and their values in the table give the scores in the matches. We then choose 8 of the remaining teams to be their opponents and see if we can construct a new table for the next round of the tournament (which will have half as many matches). And so on until we reach the last 2 teams.

      This Python 3 program runs in 1.2s.

      Run: [ @repl.it ]

      from enigma import subsets, diff, ordered, flatten, join, printf
      
      # the total goals scored/conceded
      gs0 = dict(
        A=(5, 6), B=(14, 0), C=(15, 8), D=(2, 4), E=(1, 3), F=(0, 5), G=(4, 6), H=(1, 4),
        I=(1, 2), J=(12, 12), K=(6, 5), L=(0, 1), M=(4, 5), N=(1, 5), O=(2, 3), P=(7, 6),
      )
      
      # do the list of <ls>, <ws> make a set of matches using goals scored/conceded in <gs>?
      # return list of (<winner> + <loser>, (<scored>, <conceded>))
      # and a new version of <gs> for the next round
      def matches(gs, ls, ws):
        ms = list()
        d = dict()
        for (w, l) in zip(ws, ls):
          ((fw, aw), (fl, al)) = (gs[w], gs[l])
          (f, a) = (fw - al, aw - fl)
          if f < 0 or a < 0: return (None, None)
          ms.append((w + l, (al, fl)))
          d[w] = (f, a)
        return (ms, d)
      
      # allowable score:
      # no side scores more than 5 goals, and no draws
      score = lambda x, y: not(x > 5 or y > 5 or x == y)
      
      # play out a tournament
      # k = number of matches in this round
      # gs = total number of goals scored in the remaining rounds
      # ms = match outcomes in each round
      # ss = scores used so far
      def tournament(k, gs, ms=list(), ss=set()):
        # how many matches?
        if k == 1:
          # there should be 2 teams
          (x, y) = gs.keys()
          ((fx, ax), (fy, ay)) = (gs[x], gs[y])
          if fx == ay and ax == fy and score(fx, ax):
            yield ms + [[(x + y, (fx, ax)) if fx > ax else (y + x, (fy, ay))]]
        else:
          # teams that can be knocked out in this round
          teams = list(k for (k, (f, a)) in gs.items() if score(f, a))
          # choose the losers
          for ls in subsets(teams, size=k):
            # choose the winners from the remaining teams
            for ws in subsets(diff(gs.keys(), ls), size=k, select="P"):
              (ms_, gs_) = matches(gs, ls, ws)
              if not gs_: continue
              ss_ = set(ordered(*xs) for (ts, xs) in ms_)
              if ss_.intersection(ss): continue
              yield from tournament(k // 2, gs_, ms + [ms_], ss.union(ss_))
              
      
      # there are 8 matches in the first round
      for ms in tournament(8, gs0):
        # check K is knocked out by the champions
        champ = ms[-1][0][0][0]
        if not(champ + 'K' in (ts for (ts, xs) in flatten(ms))): continue
        # output the tournament
        for (i, vs) in enumerate(ms, start=1):
          printf("Round {i}: {vs}", vs=join((f"{t[0]}v{t[1]} = {x}-{y}" for (t, (x, y)) in sorted(vs)), sep="; "))
        printf()
      

      Solution: The semi-finals were: B vs K = 3-0; C vs J = 5-3.

      So the final was: B vs C = 2-0, and B were the champions.

      The strategy given above finds two possible tournaments, but only in one of them is K knocked out by the eventual champions.

      Like

      • Frits's avatar

        Frits 8:13 pm on 18 August 2020 Permalink | Reply

        @Jim

        Did you also solve the puzzle manually?

        It is not so difficult to determine who is playing whom in the semi-finals.
        The scores are not easy to determine.

        Like

        • Jim Randell's avatar

          Jim Randell 12:00 pm on 19 August 2020 Permalink | Reply

          @Frits: I didn’t do a manual solution for this one. But I imagine the fact there are only 15 possible scores for the 15 games must make things a bit easier. (This is something I didn’t use in my program).

          Like

  • Unknown's avatar

    Jim Randell 9:55 am on 12 July 2020 Permalink | Reply
    Tags:   

    Brainteaser 1835: Dominic’s dominoes 

    From The Sunday Times, 16th November 1997 [link]

    Dominic thought up a variation of the domino jigsaw game. He laid out a standard set of dominoes and produced the pattern below by copying the numbers of spots in each place. He put a 0 for all the blanks except for the one blank which stuck out of a side of the rectangle:

    Find the positions of all the dominoes.

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1835]

     
    • Jim Randell's avatar

      Jim Randell 9:56 am on 12 July 2020 Permalink | Reply

      I used the [[ DominoGrid() ]] solver from the enigma.py library (see: Teaser 1590). We pair up one of the edge squares with a 0 to make a domino, then attempt to fit the rest into the remainder of the grid. The following program runs in 88ms.

      Run: [ @repl.it ]

      from enigma import DominoGrid, update, printf
      
      # the grid
      (X, Y, grid) = (5, 11, [
        6, 2, 6, 2, 0,
        6, 3, 1, 2, 0,
        3, 5, 1, 2, 0,
        3, 5, 3, 3, 1,
        6, 6, 5, 3, 0,
        4, 3, 0, 3, 2,
        2, 5, 4, 4, 4,
        4, 2, 4, 6, 6,
        5, 5, 4, 1, 1,
        2, 4, 1, 5, 0,
        1, 1, 0, 5, 6,
      ])
      
      # remove one of the border squares and solve for the rest
      for (i, b) in enumerate(grid):
        (y, x) = divmod(i, X)
        if x == 0 or x == X - 1 or y == 0 or y == Y - 1:
          # place the 0-b domino and solve for the remaining dominoes
          p = DominoGrid(X, Y, update(grid, [(i, None)]))
          for s in p.solve(used=[(0, b)]):
            printf("[0-{b} placed @ {x},{y}]\n")
            p.output_solution(s, prefix="  ")
      

      Solution: The layout of the dominoes is shown below:

      So the missing square is part of 0-2 domino.

      Like

  • Unknown's avatar

    Jim Randell 8:31 am on 5 July 2020 Permalink | Reply
    Tags:   

    Brainteaser 1823: The special seven 

    From The Sunday Times, 24th August 1997 [link]

    A “special seven” fraction is one whose decimal expansion uses only 7s and/or 0s. So examples of special sevens are:

    0.7707
    0.70707070…

    which are the decimal expansions of:

    7707/10000
    70/99

    respectively.

    You can set yourself all sorts of tasks with the special sevens. For example, is it possible to find some which add up to 1? In fact this is possible in many different ways, but…

    … what is the smallest number of special sevens adding to 1?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1823]

     
    • Jim Randell's avatar

      Jim Randell 8:32 am on 5 July 2020 Permalink | Reply

      Each “special seven” number corresponds to a “special one” number, which can be derived by dividing by 7.

      So if we find a collection of special sevens that sum to 1, there is a corresponding set of special ones that sum to 1/7.

      The decimal expansion of 1/7 = 0.(142857)…

      Which if we write it as a sum of special ones will require at least 8 of them to construct the 8 digit.

      Solution: The smallest number of special sevens that sum to 1 is 8.


      We can construct a collection of 8 special ones that sum to 1/7 as follows:

      0.(000100)...  [h]
      0.(000101)...  [g] = [f]
      0.(000101)...  [f]
      0.(000111)...  [e]
      0.(010111)...  [d] = [c]
      0.(010111)...  [c]
      0.(011111)...  [b]
      0.(111111)...  [a]
      -------------
      0.(142857)...
      

      (This is not the only set, the 0’s and 1’s in each column can be re-ordered to give other sets, and there is no reason why each recurring section should use the same arrangement of columns).

      Writing these as fractions (from [a] to [h]) we have:

      [a] = 0.(111111)... = 111111/999999 = 1/9
      [b] = 0.(011111)... = 11111/999999
      [c] = 0.(010111)... = 10111/999999
      [d] = 0.(010111)... = 10111/999999
      [e] = 0.(000111)... = 111/999999 = 1/9009
      [f] = 0.(000101)... = 101/999999
      [g] = 0.(000101)... = 101/999999
      [h] = 0.(000100)... = 100/999999
      

      Which sum to: 142857/999999 = 1/7 as required.

      Multiplying these values by 7 gives us a set of 8 special sevens that sum to 1:

      [a] = 0.(777777)... = 777777/999999 = 7/9
      [b] = 0.(077777)... = 77777/999999
      [c] = 0.(070777)... = 70777/999999
      [d] = 0.(070777)... = 70777/999999
      [e] = 0.(000777)... = 777/999999 = 7/9009
      [f] = 0.(000707)... = 707/999999
      [g] = 0.(000707)... = 707/999999
      [h] = 0.(000700)... = 700/999999
      

      Like

  • Unknown's avatar

    Jim Randell 8:10 am on 28 June 2020 Permalink | Reply
    Tags: by: Colin   

    Brainteaser 1822: Teasing triangles 

    From The Sunday Times, 17th August 1997 [link]

    Each of the ten line segments in the picture have been given a different whole number value from 0 to 9. A figure shown in a triangle equals the sum of the three values assigned to the sides of the triangle. The figures which have not been given from the other two triangles are the same as each other and the two add together to give a perfect square.

    What are the numbers assigned to each side?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1822]

     
    • Jim Randell's avatar

      Jim Randell 8:11 am on 28 June 2020 Permalink | Reply

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

      The following run file executes in 96ms.

      Run: [ @repl.it ]

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      # regions given
      "A + F + G = 9"
      "E + F + H = 7"
      "C + I + J = 23"
      
      # remaining regions have the same value...
      "B + G + J == D + H + I"
      # ... and sum to a square
      "is_square(B + D + G + H + I + J)"
      
      # suppress verbose output
      --template=""
      

      Solution: The numbers assigned to each line are shown below:

      Like

      • Jim Randell's avatar

        Jim Randell 12:38 pm on 30 June 2020 Permalink | Reply

        The puzzle as originally published in The Sunday Times was worded as follows:

        Each of the ten line segments in the picture have been given a different whole number value from 0 to 9. A figure shown in a triangle equals the sum of the three values assigned to the sides of the triangle. The figures which have not been given from the other two triangles when added together to give 30. What is the value assigned to CD?

        CD being the external edge of the 23 triangle (which is the value C in my solution).

        We can adjust the run-file accordingly:

        #! python -m enigma -rr
        
        SubstitutedExpression
        
        # regions given
        "A + F + G = 9"
        "E + F + H = 7"
        "C + I + J = 23"
        
        # the other two triangles added together to give 30
        "B + D + G + H + I + J = 30"
        
        --answer="C"
        
        # suppress verbose output
        --template=""
        

        And we find that there are 24 ways to fill out the numbers, but the value on the required edge is always 9.

        Like

    • GeoffR's avatar

      GeoffR 4:09 pm on 29 June 2020 Permalink | Reply

      
      % A Solution in MiniZinc
      include "globals.mzn";
      
      % using the vertex labels A,B,C,D and E (as original diagram in link)
      % plus F for the central point
      
      % outside edges of the pentagon
      var 0..9:AB; var 0..9:BC; var 0..9:CD; var 0..9:DE; var 0..9:EA;
      
      % internal lines to central point F
      var 0..9:AF; var 0..9:BF; var 0..9:CF; var 0..9:DF; var 0..9:EF;
      
      constraint all_different ([AB, BC, CD, DE, EA, AF, BF, CF, DF, EF]);
      
      % three given triangles are AEF, ABF and CDF
      constraint AF + EF + EA == 7;
      constraint AB + AF + BF == 9;
      constraint CF + DF + CD == 23;
      
      % the other two triangle sides (BCF and DEF) are the same total 
      % and the two add together to give a perfect square
      
      constraint DE + EF + DF == BF + CF + BC;
      
      set of int: sq = {16, 25, 36, 49, 64, 81};
      constraint (DE + EF + DF + BF + CF + BC) in sq;
      
      solve satisfy;
      
      % AB = 0; BC = 3; CD = 6; DE = 5; EA = 1;
      % AF = 2; BF = 7; CF = 8; DF = 9; EF = 4;
      % % time elapsed: 0.06 s
      % ----------
      % ==========
      
      

      Like

    • GeoffR's avatar

      GeoffR 1:46 pm on 8 July 2020 Permalink | Reply

      My solution below is updated for the original Sunday Times description, the solution above being the solution being based on the teaser in the book Brainteasers (2002, edited by Victor Bryant).

      
      % A Solution in MiniZinc - original Sunday Times teaser
      include "globals.mzn";
       
      % using the vertex labels A,B,C,D and E (as original ST diagram in link)
      % plus F for the central point
       
      % outside edges of the pentagon
      var 0..9:AB; var 0..9:BC; var 0..9:CD; var 0..9:DE; var 0..9:EA;
       
      % internal lines to central point F
      var 0..9:AF; var 0..9:BF; var 0..9:CF; var 0..9:DF; var 0..9:EF;
       
      constraint all_different ([AB, BC, CD, DE, EA, AF, BF, CF, DF, EF]);
       
      % three given triangles are AEF, ABF and CDF
      constraint AF + EF + EA == 7;
      constraint AB + AF + BF == 9;
      constraint CF + DF + CD == 23;
      
      % for figures in triangles not given ie triangles DEF and BCF
      constraint DE + EF + DF + BF + CF + BC == 30; 
       
      solve satisfy;
      output ["CD = " ++ show(CD) ];
      
      % CD = 9
      % ----------
      % ==========
      
      

      Like

  • Unknown's avatar

    Jim Randell 7:12 am on 18 June 2020 Permalink | Reply
    Tags:   

    Brainteaser 1819: Early bath 

    From The Sunday Times, 27th July 1997 [link]

    There are 20 teams in one country’s premier league. They each play each other once in the first half of the season, and then they each play each other a second time in the rest of the season. Each team plays each Saturday of the season, earning three points for a win and one point for a draw. At the end of the season the bottom three teams are relegated and the top team wins the league championship.

    Last season was the most boring ever. It was possible to determine the relegated teams well before the end of the season. In fact it would be impossible in any season to be able to determine the three relegated teams in fewer weeks.

    Three further Saturdays after the relegations were determined the league championship was also determined when the league leaders were in a 0-0 draw and then found that they were unassailable. There were great celebrations that night.

    At that time, how many points did the current top two teams have?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1819]

     
    • Jim Randell's avatar

      Jim Randell 7:12 am on 18 June 2020 Permalink | Reply

      After a tortuous chain of reasoning we arrive at the answer:

      In the first half of the season there are C(20, 2) = 190 matches, and then another 190 in the second half of the season. Each team plays 19 matches in the first half of the season, and another 19 matches in the second half of the season. The season lasts 38 weeks, with 10 matches played each week.

      At some point there are 3 teams doomed to relegation, as they cannot possibly catch up with any of the remaining 17 teams.

      Suppose in the first half of the tournament there are three teams that lose all their matches, except the matches they play amongst themselves, which are drawn.

      Each of the three doomed teams has only 2 points (from their draws with the other two doomed teams). If all the other 187 matches were won outright there are 187×3 = 561 points to distribute between the remaining 17 teams. This gives an average of 33 points per team. But, if one of the doomed teams were to win all their matches in the second half of the tournament they would end up with 2 + 3×19 = 59 points, so their relegation is not guaranteed by the end of the first half of the tournament.

      If we carry on for k weeks into the second half of the tournament, with each doomed team losing each of their matches, and each of the other matches being won, then how many weeks is it before enough points are accumulated, so that each of the 17 remaining teams are out of reach?

      There are (19 − k) weeks remaining and a doomed team could win all their remaining matches, so they would end with 2 + 3(19 − k) = 59 − 3k points.

      And the total number of points to be shared between the 17 remaining teams would be: 561 + 30k.

      This can happen when:

      (561 + 30k) / 17 > 59 − 3k
      561 + 30k > 1003 − 51k
      81k > 442
      k > 5.46…

      i.e. after the 6th week of the second half of the tournament, at the earliest.

      There would then be 13 weeks remaining, so a doomed team that had a sudden change of fortune could finish with 2 + 3×13 = 41 points. But by that stage in the tournament 561 + 30×6 = 741 points could have been scored by the remaining 17 teams, which is enough for each of them to have accumulated at 43 points each. So the doomed teams can indeed be doomed to relegation.

      Now after three more weeks, i.e. after the 9th week of the second half of the tournament, with 10 weeks remaining, the championship was determined. So the team with the most points must be more than 30 points ahead of the next highest team.

      If we go back to 6th week of the second half of the tournament, then 16 of the 17 non-doomed teams could have 42 points, and the other team could have 69 points. So they are 27 points ahead.

      If they win the following 2 weeks, and the week after that they draw (as we are told in the puzzle text), then after the 9th week they have 76 points, and in order to be unassailable the next highest team can have no more than 45.

      So now we need to make sure none of the other 16 teams can get more than 45 points by the end of week 9. An easy way is to suppose all the matches apart from the ones involving the future champions are drawn.

      Then at the end of the 7th week, the best any of the 16 challengers can do is 43 points. The future champions have 72 points, and there are 12 weeks remaining, so they are assailable.

      At the end of the 8th week, the best any of the challengers can do is 44 points. The future champions have 75 points, and there are 11 weeks remaining, so they are still assailable.

      At the end of the 9th week, the best any of the challengers can do is 45 points. The future champions have 76 points, and there are 10 weeks remaining, so they are now unassailable.

      So this is a viable scenario for the puzzle.

      Solution: The top team had 76 points, and the next highest team had 45 points.

      Like

      • John Crabtree's avatar

        John Crabtree 5:14 pm on 19 June 2020 Permalink | Reply

        This teaser just works. After 6 weeks of the second half, 16 teams have 42 points and one has 69, ie a total of 741 for those teams and the maximum possible.

        Like

  • Unknown's avatar

    Jim Randell 9:19 am on 26 April 2020 Permalink | Reply
    Tags: by: Jonathan Welton   

    Brainteaser 1814: Clear heads 

    From The Sunday Times, 22nd June 1997 [link]

    “I have affixed a card to each of your foreheads”, explained the professor of logic to his three most able students. All three were perfect logicians capable of instantly deducing the logical consequences of any statement.

    He continued: “You can see the others’ cards, but none of you can see your own. On each card is written a positive whole number and one of the numbers is the sum of the other two”.

    The professor turned to the first student, Albert: “From what you can see and what you have heard, can you deduce the number on your card?”. Albert could not.

    The professor then asked Bertrand the same question. He could not deduce the number on his card.

    Likewise, when asked next, Charles could not deduce the number on his card.

    The professor then asked Albert the same question again and this time Albert was able to deduce that the number on his card was 50.

    What number was on Bertrand’s card, and what number was on Charles’s card?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1814]

     
    • Jim Randell's avatar

      Jim Randell 9:20 am on 26 April 2020 Permalink | Reply

      Each person can see two numbers, and knows their own number must be either the sum or difference of these two numbers.

      So when A is asked, the only way he would be able to narrow this choice down to a single number is if B and C’s numbers are the same, as the difference would be zero, and this is not allowed, so he would know his own number was the sum of B and C’s numbers. So A will be able to declare at the first question only if the set numbers is of the form (2n, n, n).

      Similarly, when B is asked, he will be able to declare if the set of numbers is of the form (n, 2n, n).

      But we also know that if B sees (2n, ?, n) that his own number must be 3n or n, but it cannot be n, as A would have declared if the numbers were (2n, n, n). So B can also declare if the sets of numbers are of the form (2n, 3n, n).

      When C is asked, he can declare if the numbers of the form: (n, n, 2n), (2n, n, 3n), (n, 2n, 3n), (2n, 3n, 5n).

      A is then asked again, and this time declares. So the numbers must fit one of the following patterns:

      (3n, 2n, n)
      (4n, 3n, n)
      (3n, n, 2n)
      (4n, n, 3n)
      (5n, 2n, 3n)
      (8n, 3n, 5n)

      Of these patterns, only one gives integer values when the first element is 50:

      (5n, 2n, 3n) = (50, 20, 30)

      Solution: Bertrand’s number was 20. Charles’s number was 30.


      Here is a Python program that generates the appropriate patterns for each question, and then determines what sequences of numbers match the patterns for the 4th question. It runs in 73ms.

      Run: [ @repl.it ]

      from enigma import irange, inf, flatten, div, printf
      
      # update pattern p, element i becomes the sum of the other elements
      def update(p, i):
        p = list(p)
        p[i] = sum(p) - p[i]
        return p
      
      # produce patterns that lead to declarations for A, B, C, A, B, C, ...
      def declare():
        ds = list()
        for i in irange(0, inf):
          ps = list()
          # initial seeds
          if i < 3: ps.append(update([1, 1, 1], i))
          # add in alternatives from the previous rounds
          j = i % 3
          for p in flatten(ds):
            ps.append(update(p, j))
          yield ps
          # keep the previous 2 rounds
          ds.append(ps)
          if len(ds) > 2: ds.pop(0)
      
      # find declaration patterns that correspond to the 4th question
      for (i, ps) in enumerate(declare(), start=1):
        printf("[{i} -> {ps}]")
        if i == 4: break
      
      # given A calculate B and C from the patterns
      A = 50
      for (a, b, c) in ps:
        (B, C) = (div(b * A, a), div(c * A, a))
        if B and C:
          printf("A={A} B={B} C={C}")
      

      Like

  • Unknown's avatar

    Jim Randell 12:02 pm on 16 April 2020 Permalink | Reply
    Tags:   

    Brainteaser 1808: Next choice 

    From The Sunday Times, 11th May 1997 [link]

    Much nonsense is written about the lottery. It is true that there are about 14 million different choices of six numbers from 1 to 49, but often surprise is expressed when the winning six include at least two consecutive numbers. In common with a lot of people, when I choose my numbers I make sure that they are well spread out, thus fitting in with the usual conception that it is unlikely that consecutive numbers will be drawn.

    This set me thinking about what proportion of the 14 million possible choices of 6 numbers actually contained no two consecutive numbers. The answer is surprising and neat. So, in percentages, to the nearest whole number, what proportion of the choices include no consecutive numbers?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1808]

     
    • Jim Randell's avatar

      Jim Randell 12:02 pm on 16 April 2020 Permalink | Reply

      We have already tackled a very similar puzzle with Enigma 1029 (also set by Victor Bryant under the pseudonym Susan Denham).

      The number of ways to choose 6 numbers from 49 is:

      C(49, 6) = 49! / (6! (49 − 6)!) = 13,983,816

      The number of ways to choose 6 non-consecutive numbers from 49 is:

      C(49 − 5, 6) = 44! / (6! (44 − 6)!) = 7,059,052

      This is approximately 50.48% of the total number of choices. So there are slightly more non-consecutive choices than consecutive choices.

      Solution: Approximately 50% of choices are non-consecutive.

      Like

  • Unknown's avatar

    Jim Randell 3:34 pm on 7 April 2020 Permalink | Reply
    Tags: by: WT Blunt   

    Brainteaser 1805: Find the deuce 

    From The Sunday Times, 20th April 1997 [link]

    Adam, Bill, Charlie and Dave play a game using the ace (counting as 1) and 2 to 10 of spades. These cards are shuffled and placed face down on the table. Each player in turn draws one card and declares whether it is odd or even. Each then in turn draws a further card and must declare a number being either the sum or the product of the two cards held. The winner is the first to deduce which cards remain on the table. They are all perfect logicians, draw every possible inference, and rely on the fact that the others do too.

    In a recent game the calls went as follows:

    Adam: “odd”
    Bill: “odd”
    Charlie: “odd”
    Dave: “odd”
    Adam: “6”
    Bill: “12”
    Charlie: “15”

    But as Dave reached for his second card, a player claimed the game.

    Who was the winner and where was the 2?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1805]

     
    • Jim Randell's avatar

      Jim Randell 3:34 pm on 7 April 2020 Permalink | Reply

      They could just have easily played the game with 10 cards numbered 1 to 10.

      There are 5 odd cards (1, 3, 5, 7, 9) and only four players, so no one can win from the first round.

      This Python program collects the possible sequences of cards, and then works out it any of the players can determine the cards in the sequence given that they know their own cards. (If you can determine the cards in the sequence, you know which cards remain on the table). And then repeats this until the set of possible sequences remains unchanged (so all deductions have been made). It then moves on to the next play described in the text, with no-one winning until after C has drawn his second card. D is about to draw his second card when someone else claims victory.

      This Python program runs in 88ms.

      Run: [ @repl.it ]

      from enigma import irange, subsets, filter_unique, ordered, intersect, printf
      
      # cards
      cards = set(irange(1, 10))
      
      # collect hand for player k from a sequence of cards
      def hand(s, k, n=4):
        return ordered(*(s[i] for i in irange(k, len(s) - 1, step=n)))
      
      # find wins from sequences ss
      def win(ss):
        r = dict()
        us = list()
        # can player k win?
        for (i, k) in enumerate("ABCD"):
          (rk, uk) = filter_unique(ss, (lambda s: hand(s, i)), (lambda s: ordered(*s)))
          if rk: r[k] = rk
          us.append(uk)
        # return wins (dict), and sequences that do not give a win (set)
        return (r, intersect(us))
      
      # analyse sequences ss
      def analyse(ss):
        n = len(ss)
        while True:
          (r, ss) = win(ss)
          yield (r, ss)
          m = len(ss)
          if m == n: break
          n = m
      
      # play a card for player k, who delares d
      def play(ss, k, d):
        for s in ss:
          for x in cards.difference(s):
            if x + s[k] == d or x * s[k] == d:
              yield s + (x,)
      
      # the first four plays are all odd cards
      ss = list(subsets((1, 3, 5, 7, 9), size=4, select="P"))
      
      # no-one wins
      for (r, ss) in analyse(ss): pass
      
      # A (player 0) declares 6
      ss = list(play(ss, 0, 6))
      
      # no-one wins
      for (r, ss) in analyse(ss): pass
      
      # B (player 1) declares 12
      ss = list(play(ss, 1, 12))
      
      # no-one wins
      for (r, ss) in analyse(ss): pass
      
      # C (player 2) declares 15
      ss = list(play(ss, 2, 15))
      
      # someone (other than D) wins
      for (r, ss) in analyse(ss):
        if r and 'D' not in r:
          for k in sorted(r.keys()):
            for v in r[k]:
              printf("{k} wins: {v}")
          break
      

      Solution: Charlie won. The 2 remained on the table.

      I agree with the published answer, but not with the full solution given at the back of the book.

      My solution is that C claims victory and the final situation when C wins is:

      A: 1 then 6
      B: 3 then 4
      C: 5 then 10 (or: 7 then 8)
      D: 9
      table: 2, 7, 8 (or: 2, 5, 10)

      It makes sense that C is the one who can claim victory as he could be holding (5, 10) or (7, 8), and only C knows for sure.


      The solution given in the book [ link ] says that the final situation when C wins is:

      A: 1 then 5 (or: 5 then 1)
      B: 3 then 4
      C: 9 then 6
      D: 7
      table: 2, 8 [and, presumably, 10]

      However the first four cards are odd, and if A drew the last remaining odd card, then he would know that the cards that remained on the table at this point were the 5 even cards and would claim victory.

      So this cannot be the situation (and given that A did not claim victory as soon as he drew his second card everyone would know that A cannot have 1 and 5 (so must have 3 and 2, or 1 and 6)).

      Like

      • John Crabtree's avatar

        John Crabtree 6:16 am on 10 April 2020 Permalink | Reply

        D does not win. Summarizing the successive elimination:
        After A’s 2nd call, if A = 1 + 5, A wins. Everybody knows this. This eliminates (a) and (b).
        After B’s 2nd call, if B = 3 + 9, B wins. Everybody knows this. This eliminates (c) and (d).
        After C’s 2nd call, if D = 1, 5 or 7, D wins. This eliminates (e), (g) and (i).
        This leaves two cases, (f) and (h) as noted by Jim.
        And so C wins and the 2 is on the table.

        It is ironic that the published solution was correct, but for the wrong reasons.

        Like

  • Unknown's avatar

    Jim Randell 8:17 am on 17 March 2020 Permalink | Reply
    Tags: ,   

    Brainteaser 1798: Trisection 

    From The Sunday Times, 2nd March 1997 [link]

    We have taken a piece of paper in the shape of an equilateral triangle and folded it so that one of the corners lies at some point on the opposite side:

    In the figure triangle A has an area of 36 cm²  and triangle B has an area of 16 cm².

    What is the area of the unfolded piece of paper?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1798]

     
    • Jim Randell's avatar

      Jim Randell 8:17 am on 17 March 2020 Permalink | Reply

      (See also: Enigma 1402).

      We note that triangles A and B are similar (they both have angles of (60°, θ, 120° − θ)).

      And their areas are in the ratio 36:16 = 6²:4², so their sides are in the ratio 6:4 = 3:2.

      We can label the sides of A as (3x, 3y, 3z) and of B as (2x, 2y, 2z).

      Looking at the base of the original triangle we see it has a length of: (2x + 3y)

      And so the the missing lengths on the other sides are: (3y − x) and (2x + y)

      But these are also the lengths of the remaining sides of triangles A and B, hence:

      (3y − x) / (2x + y) = 3 / 2
      6y − 2x = 6x + 3y
      3y = 8x

      So triangle A has sides of 3x and 8x, separated by an angle of 60°, and it has an area of 36, so:

      36 = (1/2)(3x)(8x)sin(60°)
      36 = 6x²√3
      x²√3 = 6

      And the base of the original triangle is 8x + 2x = 10x, so the total area is:

      T = (√3/4)(10x)²
      T = 25x²√3
      T = 25×6 = 150

      Hence:

      Solution: The area of the original triangle is 150 cm².

      Like

  • Unknown's avatar

    Jim Randell 8:13 am on 10 March 2020 Permalink | Reply
    Tags:   

    Brainteaser 1791: Untied problem 

    From The Sunday Times, 12th January 1997 [link]

    Here is an exact long division sum. In some places digits have been consistently replaced by letters, with different letters used for different digits. In all other places the digits have been replaced by asterisks.

    Untie this and find UNTIED.

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book and differs slightly from the original puzzle.

    [teaser1791]

     
    • Jim Randell's avatar

      Jim Randell 8:13 am on 10 March 2020 Permalink | Reply

      We can use the [[ SubstitutedDivision() ]] solver from the enigma.py library to solve this puzzle.

      The following run file executes in 147ms.

      Run: [ @repl.it ]

      #!/usr/bin/env python -m enigma -r
      
      SubstitutedDivision
      
      "UNTIED / JIM = ADAM"
      
      "UNT - ??? = ??"
      "??? - ??? = ??"
      "??? - ??D = ??"
      "??? - ??? = 0"
      
      --answer="UNTIED"
      

      Solution: UNTIED = 986304.

      The correct division sum is: 986304 ÷ 132 = 7472.

      Like

    • GeoffR's avatar

      GeoffR 6:32 pm on 10 March 2020 Permalink | Reply

      
      from itertools import permutations
      
      for P in permutations('1234567890', 9):
          j, i, m, u, n, t, e, d, a = P
      
          # leading digits must not be zero
          if j == '0' or a =='0'or u == '0': continue
          jim = int(j + i + m)
          untied = int(u + n + t + i + e + d)
          adam = int(a + d + a + m)
          if jim * adam == untied:
              
              # check the lone 'D' position is correct
              if (int(a) * jim) % 10 == int(d):
                print (f"Sum is {untied} / {jim} = {adam}")
                
      # Sum is 986304 / 132 = 7472
      
      # There are only two solutions to the main division sum:
      # 986304 / 132 = 7472
      # and 785601 / 369 = 2129
      
      # Checking the lone 'D' digit position is enough to eliminate the
      # second solution ie 785601 / 369 =  2129. The last line of the
      # second solution also has 4 digits, instead of 3 digits.
      # It ran in 112 msec.
      
      
      

      Like

  • Unknown's avatar

    Jim Randell 11:50 am on 27 February 2020 Permalink | Reply
    Tags:   

    Brainteaser 1785: Back to front 

    From The Sunday Times, 1st December 1996 [link]

    Given a row of eleven playing cards:

    [J] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1]

    I wish to reverse the order to give:

    [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [J]

    To do this we are allowed at any stage to make a “move” of the following type:

    remove any section of adjacent cards from the pack and move them elsewhere.

    For example, one possible move from the starting position would be to take:

    [9] [8] [7]

    and move it to the right to give:

    [J] [10] [6] [5] [9] [8] [7] [4] [3] [2] [1]

    What is the minimum number of moves required to reverse them?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book and differs slightly from the original puzzle.

    [teaser1785]

     
    • Jim Randell's avatar

      Jim Randell 11:51 am on 27 February 2020 Permalink | Reply

      (See also: Puzzle #32).

      We can measure the “disorderedness” of a list by going through it and looking how each element compares to the next element. If it is less than the next element, then it is “ordered”. If it is greater than the next element, then it is “disordered”.

      Looking at the initial list we have:

      [11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

      which gives the following pairs:

      (11, 10) (10, 9) (9, 8) (8, 7) (7, 6) (6, 5) (5, 4) (4, 3) (3, 2) (2, 1)

      all of which are disordered, giving the initial list a score of 10.

      The target list is:

      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

      which gives the following pairs:

      (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) (7, 8) (8, 9) (9, 10) (10, 11)

      all of which are ordered, give the target list a score of 0.

      Suppose the list is:

      [? … a] [b … c] [d … e] [f … ?]

      And we move the [b … c] section to between e and f.

      Then we end up with

      [? … a] [d … e] [b … c] [f … ?]

      In the process we lose the adjacent pairs (a, b) (c, d) (e, f) and we gain the adjacent pairs (a, d) (e, b) (c, f).

      So the best improvement we could hope for is if the first three pairs are disordered, and the second three pairs are ordered, then we has reduced the disorderedness score by 3.

      For this to happen we need:

      a > b
      c > d
      e > f

      and:

      a < d
      e < b
      c < f

      We can write all six inequalities as the following chain:

      a < d < c < f < e < b < a

      So it is not possible for all the inequalities to hold simultaneously. So the best we can hope for in a move is to reduce the disorderedness score by 2.

      A similar argument holds if a block is moved to the left.

      Furthermore, if we consider the first move, we know the values a, b, c, d, e, f are in descending order. So the pairs (a, b), (c, d), (e, f) are disordered, and of the pairs (a, d) (e, b) (c, f) only (e, b) is ordered, so we can only reduce the disorderedness by 1 on the first move.

      Similarly, on the final move the list ends up correctly ordered, and a similar argument shows that we can only reduce the disorderedness by 1 on the final move.

      So, for a sequence of length 11, we start with a disorderedness score of 10, and to reduce this to a disorderedness score of 0 will require at least 6 moves (the score being reduced by 1+2+2+2+2+1 = 10). In general reversing a sequence of length n > 2 will require at least 1 + [n / 2] moves (where [x] denotes the integer part of x).

      But can we achieve a reversal in 6 moves?

      I wrote a program to try.

      The following program can be used to examine the behaviour of sequences up to length 9 in less than 7s (and length 10 takes 23 minutes). All of these were achievable with the expected minimum number of moves. Unfortunately we want to know about sequences of length 11 (which takes 93m).

      However, in my experiments with smaller sequences, I found that the minimal sequence found always had as an initial move, removing the two leftmost elements, and then re-inserting them at position (m − 1) // 2 (where m is the length of the original sequence).

      Using this as the first move reduces the run time for a length 10 sequence to 6s, and produces a solution of 6 moves for a length 11 sequence in just 29s.

      Run: [ @replit ]

      from enigma import (irange, inf, subsets, first, arg, printf)
      
      # start with a [1..m] list, reversed
      m = arg(9, 0, int)
      f = arg(1, 1, int)
      printf("[m={m}, f={f}]")
      
      # collect possible different moves
      move = dict()
      s = list(irange(0, m - 1))
      for (i, j) in subsets(irange(0, m - 1), size=2):
        for k in irange(1, m - j + i - 1):
          if k == i: continue
          r = s[i:j + 1]
          t = s[:i] + s[j + 1:]
          r = t[:k] + r + t[k:]
          if r not in move.values():
            move[(i, j, k)] = r
      
      # disorderedness score
      def score(s):
        r = 0
        a = None
        for b in s:
          if a is not None: r += (a > b)
          a = b
        return r
      
      # sort s in n (or fewer moves)
      def solve(s, n, d, ms=[]):
        # are we done?
        if d == 0:
          yield ms
        elif n > 0:
          # choose a move
          (diff1, diff2) = (list(), 0)
          for (m, v) in move.items():
            s1 = list(s[x] for x in v)
            d1 = score(s1)
            diff = d - d1
            if diff == 2:
              # try diff 2
              yield from solve(s1, n - 1, d1, ms + [m])
              diff2 += 1
            elif diff == 1:
              # save up diff 1
              diff1.append((s1, d1, m))
          # try any diff 1 moves
          if not diff2:
            for (s1, d1, m) in diff1:
              yield from solve(s1, n - 1, d1, ms + [m])
      
      s0 = list(irange(m, 1, step=-1))
      for n in irange(1 + m // 2, inf):
      
        # make an initial move...
        if f:
          m1 = (0, 1, (m - 1) // 2)
          s1 = list(s0[x] for x in move[m1])
          (s, n, ms) = (s1, n - 1, [m1])
        else:
          (s, ms) = (s0, [])
      
        ss = first(solve(s, n, score(s), ms), 1)
        for ms in ss:
          # output solution
          printf("n={n}: {ms}", n=len(ms))
          s = s0
          for (i, j, k) in ms:
            t = list(s[x] for x in move[(i, j, k)])
            printf("  [{i}, {j}] @ {k}: {s} -> {t} ({ss} -> {st})", ss=score(s), st=score(t))
            s = t
          printf()
        if ss: break
      

      Solution: The minimum number of moves required is 6.

      Here is one set of 6 moves that achieves the reversal:

      (Adjacent pairs that are ordered are linked with a hyphen).

      Like

    • Jim Randell's avatar

      Jim Randell 11:19 am on 1 March 2020 Permalink | Reply

      John Crabtree has come up with the following procedure to reverse a sequence using a minimal number of moves.

      The first move partitions the sequence into an ordered sequence (to the left) and a subsequence from which ordered pairs can be removed and inserted into the ordered sequence (to the right). The total number of moves required is 1 + [n / 2].

      Here is the procedure used to reverse a length 11 sequence in 6 moves:

      And here is the procedure encapsulated in a Python program:

      Run: [ @replit ]

      from enigma import (irange, tuples, arg, printf)
      
      # generate the moves to reverse a sequence of length n
      def reverse(n):
        if n < 3:
          if n == 2: yield (1, 1, 0)
          return
        (h, r) = divmod(n, 2)
        # 1st move
        yield (h + r, n - 1, r)
        # then move successive pairs into position
        for k in irange(0, h - 1):
          i = k + h + r - 1
          j = i + 1
          yield (i, j, k)
          
      
      # disorderedness score
      score = lambda s: sum(a > b for (a, b) in tuples(s, 2))
      
      # make a block move
      def move(s, i, j, k):
        r = s[i:j + 1]
        t = s[:i] + s[j + 1:]
        return t[:k] + r + t[k:]
      
      n = arg(11, 0, int)
      
      # collect the moves
      ms = list(reverse(n))
      printf("[n={n}, {m} moves]", m=len(ms))
      s = list(irange(n, 1, step=-1))
      for (i, j, k) in ms:
        t = move(s, i, j, k)
        printf("  [{i}, {j}] @ {k}: {s} -> {t} ({ss} -> {st})", ss=score(s), st=score(t))
        s = t
      printf()
      

      Like

    • Lise Andreasen's avatar

      Lise Andreasen 2:01 am on 18 October 2024 Permalink | Reply

      Very nice analysis!

      Liked by 1 person

  • Unknown's avatar

    Jim Randell 9:42 am on 2 January 2020 Permalink | Reply
    Tags: by: Sir Bryan Thwaites   

    Brainteaser 1783: Nine, eight, seven, … 

    From The Sunday Times, 17th November 1996 [link]

    If you place a digit in each of the above boxes then you can read some numbers horizontally (left to right), vertically (top to bottom) and diagonally (top left to bottom right and bottom left to top right).

    Your task is to place:

    • nine digits, one in each box, so that you can then read …
    • eight three-figure numbers, at least …
    • seven of which are different primes, and so that at least …
    • six of the eight are palindromic, and so that at least …
    • five of the digits in the bottom two rows are odd.

    Fill in the boxes.

    This puzzle is included in the book Brainteasers (2002) under the title “Nine, Eight, Seven, Six, …”. The puzzle text above is taken from the book. In the original puzzle the final condition (“five …”) was not included, and the required answer was just the value of the digit in the central box.

    [teaser1783]

     
    • Jim Randell's avatar

      Jim Randell 9:44 am on 2 January 2020 Permalink | Reply

      If we label the grid as follows:

      then the 8 numbers we are interested in are:

      ABC, DEF, GHI, ADG, BEH, CFI, AEI, GEC

      We can use the [[ SubstitutedExpression() ]] solver from the enigma.py library to solve the puzzle directly, but it is a bit slow. (It takes over 5 minutes to run to completion).

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --distinct=""
      
      # at least seven of the numbers are different primes
      "icount(set([ABC, DEF, GHI, ADG, BEH, CFI, AEI, GEC]), is_prime) > 6"
      
      # at least six of them are palindromic
      "icount([ABC, DEF, GHI, ADG, BEH, CFI, AEI, GEC], is_npalindrome) > 5"
      
      # at least five of the digits in the bottom two rows are odd
      --code="is_odd = lambda x: x % 2 == 1"
      "icount([D, E, F, G, H, I], is_odd) > 4"
      
      # solution
      --answer="(ABC, DEF, GHI)"
      

      So we can do some analysis to make things a bit easier:

      If a number is a palindrome, then its first and last digit are the same.

      Looking at the 6 numbers: ABC, GHI, ADG, CFI, AEI, GEC, we get the following graph equating the values of symbols if they are all palindromes:

      But at most 2 of them are not necessarily palindromes, and it is not possible to remove just 2 edges from the graph to form a disconnected segment.

      Hence A, C, G, I must all be the same (odd) digit (say, X).

      So we can consider the grid:

      and the 8 numbers are:

      XBX, DEF, XHX, XDX, BEH, XFX, XEX, XEX

      We see that the two diagonals take on the same value, so there are actually only 7 different numbers (all of which must all be prime), and 6 of the numbers are palindromes by definition, so we don’t need to worry about looking for additional palindromes.

      The following run file executes in 486ms.

      Run: [ @replit ]

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      # there are 7 different primes
      "icount(set([XBX, DEF, XHX, XDX, BEH, XFX, XEX]), is_prime) > 6"
      
      # at least five of the digits in the bottom two rows are odd
      --code="is_odd = lambda x: x % 2 == 1"
      "icount([D, E, F, X, H, X], is_odd) > 4"
      
      # solution
      --answer="(XBX, DEF, XHX)"
      

      Solution: The completed grid is:

      So the eight numbers are:

      181 (prime, palindrome)
      503 (prime)
      191 (prime, palindrome)
      151 (prime, palindrome)
      809 (prime)
      131 (prime, palindrome)
      101 (prime, palindrome)
      101 (prime, palindrome)

      There are 7 different primes and 6 palindromes. The number 101 is repeated.

      Without the constraint that at least 5 of the 6 numbers in the bottom two rows are odd we can also have the following reflection:

      But in both cases the central square contains the digit 0.

      Like

    • GeoffR's avatar

      GeoffR 10:40 am on 3 January 2020 Permalink | Reply

      I used Jim’s alternative grid to find a permutation solution

      
      # ABC   XBX
      # DEF   DEF
      # GHI   XHX
      
      from time import perf_counter_ns
      start = perf_counter_ns()
      
      from enigma import is_prime
      list_pal =[]
      
      def is_pal3(abc):
          a = abc // 100
          b = abc //10 % 10
          c = abc % 10
          if a == c and b != a:
              return True
          return False
      
      from itertools import permutations
      for p in permutations('1234567890',6):
        x, b, d, e, f, h = p
        if any (z == '0' for z in (x, h, d, f, b)): continue
        # nos are xbx, DEF, xhx, xdx, beh, xfx, xex
        xbx, DEF = int(x+b+x), int(d+e+f)
        xhx, xdx = int(x+h+x), int(x+d+x)
        beh, xfx, xex = int(b+e+h), int(x+f+x), int(x+e+x)
        if all(is_prime(z) for z in (xbx, DEF, xhx, xdx, beh, xfx, xex)):
          # check for palindrome numbers 
          if is_pal3(xbx): list_pal.append(xbx)
          if is_pal3(DEF): list_pal.append(DEF)
          if is_pal3(xhx): list_pal.append(xhx)
          if is_pal3(xdx): list_pal.append(xdx)
          if is_pal3(beh): list_pal.append(beh)
          if is_pal3(xfx): list_pal.append(xfx)
          if is_pal3(xex): list_pal.append(xex)
          
          # we are looking for five palindromes in this grid
          if len(set(list_pal)) == 5:
            # check there are 4 odd digits in bottom two rows in this grid
            set_odd = set()
            if int(d) % 2 == 1: set_odd.add(d)
            if int(e) % 2 == 1: set_odd.add(e)
            if int(f) % 2 == 1: set_odd.add(f)
            if int(x) % 2 == 1: set_odd.add(x)
            if int(h) % 2 == 1: set_odd.add(h)
            if len(set_odd) == 4:
              # print the 3 by 3 grid
              print(xbx)
              print(DEF)
              print(xhx)
              print(f"{(perf_counter_ns() - start) / 1e6:.3f} ms")
      
      # 181
      # 503
      # 191
      # 144.905 ms
      
      
      

      Like

    • GeoffR's avatar

      GeoffR 3:56 pm on 6 January 2020 Permalink | Reply

      I used two list comprehensions in Python to shorten my code, which also meant I could omit the palindrome function.

      
      # Grid rows are: XBX, DEF and XHX
      from itertools import permutations
      from enigma import is_prime
      
      pal3, odd = [], []
      
      for p in permutations('1234567890', 6):
        x, b, d, e, f, h = p
        if any (z == '0' for z in (x, h, d, f, b)): continue
        
        # Seven grid numbers are xbx, DEF, xhx, xdx, beh, xfx, xex
        xbx, DEF = int(x + b + x), int(d + e + f)
        xhx, xdx = int(x + h + x), int(x + d + x)
        beh, xfx, xex = int(b + e + h), int(x + f + x), int(x + e + x)
         
        # check all seven numbers are prime
        if all(is_prime(z) for z in (xbx, DEF, xhx, xdx, beh, xfx, xex)):
            
          # check for five palindrome numbers
          pal3 = [ x for x in (xbx, DEF, xhx, xdx, beh, xfx, xex) \
                  if (x // 100 == x % 10 and x // 100 != x // 10 % 10)]    
          if len(pal3) == 5:
              
            # check for four odd digits in bottom two rows of grid
            odd = [int(z) for z in (d, e, f, x, h) if int(z) % 2 == 1]
            if len(odd) == 4:
              print(f"Grid rows are: {xbx}, {DEF}, {xhx} ")
              
      # Grid rows are: 181, 503, 191 
      
      

      Like

  • Unknown's avatar

    Jim Randell 8:37 am on 22 December 2019 Permalink | Reply
    Tags: ,   

    Brainteaser 1782: Unwinding 

    From The Sunday Times, 10th November 1996 [link]

    Our Vienna clock will run for about eight days when fully wound, so I wind it up each Sunday morning. But last Sunday this caused a problem as, after I had wound it up, the hands started rotating at many times their normal speed. Thereafter they slowed down at a steady rate until they stopped sometime after 5pm.

    Interestingly, they told the correct time on the hour at each hour between winding up and stopping.

    What was the correct time when the clock stopped?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1782]

     
    • Jim Randell's avatar

      Jim Randell 8:38 am on 22 December 2019 Permalink | Reply

      The clock undergoes a period when the hands are rotating (rotating at a constant rate) much faster that normal. Then, at some point, they begin to slow (slowing at a constant rate) until the hands stop completely, some time after 5pm.

      Presumably this happens when the hands indicate a time of “about 8 days” (say 180 – 204 hours) from the winding time (which is sometime before 12pm).

      I made some assumptions to simplify the programming:

      Having not heard of a “Vienna clock” I assumed the clock was a normal 12 hour timepiece.

      I assumed the clock was wound up sometime between 11am and 12pm, and set off advancing at many times normal speed, but at some point at or before 12pm started slowing. After that the amount advanced by the clock at 12pm, 1pm, 2pm, 3pm, 4pm, 5pm, was sufficient that the clock showed the correct time. So each one was actually displaying a time exactly some multiple of 12 hours in advance of the actual time. The clock then stopped sometime between 5pm and 6pm (actual time).

      The following Python code examines this situation. It runs in 289ms.

      Run: [ @repl.it ]

      from fractions import Fraction as F
      from enigma import (irange, Polynomial, nsplit, div, sprintf as f)
      
      # format time t as hh:mm:ss.ss
      def hms(t, fmt="{h:d}:{m:02d}:{s:05.2f}"):
        (t, r) = divmod(3600.0 * t, 1)
        (h, m, s) = nsplit(int(t), base=60)
        s += r
        return f(fmt)
      
      # consider number of hours advanced at 12pm
      for h0 in irange(12, 192, step=12):
        # at 1pm
        for h1 in irange(h0 + 1, 193, step=12):
          # at 2pm
          for h2 in irange(h1 + 1, 194, step=12):
            # use the three points to determine the quadratic equation
            # y = a.x^2 + b.x + c
            q = Polynomial.interpolate([(0, h0), (1, h1), (2, h2)])
            if q is None or len(q) < 3: continue
            (c, b, a) = q
      
            # does it achieve a maximum in [5, 6]
            if not(a < 0): continue
            m = F(-b, 2 * a)
            if not (5 < m < 6): continue
      
            # check the times at 3pm, 4pm, 5pm
            hs = [h0, h1, h2]
            for x in (3, 4, 5):
              y = div(q(x), 1)
              if y is not None and y % 12 == x:
                hs.append(y)
            if len(hs) < 6: continue
      
            # find the earliest start time
            s = F(h0, 1 - b)
            if not (-1 < s < 0): continue
      
            # check the total time advanced is in the required range (7.5 - 8.5 days)
            t = q(m) - s
            if not (180 < t < 204): continue
      
            print(f("stop={m} [hs={hs}, start={s}, total={t:.2f}h]", m=hms(m), s=hms(s % 12), t=float(t)))
      

      Solution: The correct time when the clock stopped was 5:35pm.


      We find a solution, with the number of hours advanced from 12pm at (12pm, 1pm, 2pm, 3pm, 4pm, 5pm) as follows:

      (+12, +73, +122, +159, +184, +197)

      The residues mod 12 of each of the values are:

      (0, 1, 2, 3, 4, 5)

      So we see that the clock would show the correct time on each hour.

      The differences between the successive terms of the sequences are:

      (61, 49, 37, 25, 13)

      Each term decreases by 12 from the previous one, so the clock is slowing at a constant rate, and comes to a stop at x = 67/12, which corresponds to 5:35pm.

      The corresponding quadratic equation is:

      y(x) = −6x² + 67x + 12

      At 12pm the clock is advancing at 67× normal speed (y'(0) = 67), so the maximum possible time after winding would be if immediately after winding, the clock set off at a constant 67× normal speed until 12pm, at which point it began to slow down.

      This places the earliest winding time at 11:49:05.5am.

      If the clock starts advancing at 67× normal speed at this time, then in the first 9.8 seconds it advances to show 12:00, and in the remaining 10m44.8s it advances another 12 hours, so that at 12pm (actual time) the clock shows 12:00.

      In the following hours the slowing clock advances an appropriate number of hours to show the correct time on each hour, until it stops at 5:35pm. In the time since winding it has advanced 199.22 hours, approximately 8.3 days, which is in the range we are expecting.

      If the clock started slowing before 12pm than it would be running at faster than 67× normal rate after winding, and the time of the winding would be closer to 12pm. But the total amount the clock has advanced is at least 197 hours (= 8.2 days), so we still get a viable answer.


      However, if it is possible that the clock was running at a constant speed until some time after 12pm, then we can get different answers to the published solution.

      For example, if the number of hours advanced at (12pm, 1pm, 2pm, 3pm, 4pm, 5pm) is:

      (+12, +49, +86, +123, +160, +197)

      The the correct time is displayed at the required times, and each value is 37 hours advanced from the previous value, so the clock is advancing at a constant rate of 37× normal speed. The time the clock was wound up was 11:40:00am.

      At (or after) 5pm the clock can be begin to slow and finally run down at whatever time we choose (between 5pm and 6pm).

      For example, if, at 5pm, the clock slows according to the following equation:

      y(x) = −74x² + 777x − 1838

      Then we have y(5) = 197, y'(5) = 37, y'(5.25) = 0, so y achieves a maximum at y(5.25) = 201.625.

      Which means the clock stops at 5:15pm, having advanced 201.96 hours (= 8.4 days). Which provides a viable alternative solution.

      So we do need to make some additional assumptions in order to arrive at a unique solution. The one I’ve highlighted in bold above is probably the key one.

      Like

      • John Crabtree's avatar

        John Crabtree 1:53 am on 23 December 2019 Permalink | Reply

        From 4.00pm to 5.00pm the clock traveled 13 hours
        From 3.00pm to 4.00pm the clock traveled 25 hours
        From 2.00pm to 3.00pm the clock traveled 37 hours
        From 1.00pm to 2.00pm the clock traveled 49 hours
        From 12.00pm to 1.00pm the clock traveled 61 hours
        That is a little over 7.5 days, and so the clock started some time before 12.00pm, and the rate of decrease is correct.

        Let the relative speed at 4.30pm, ie the average of the speeds at 4.00 and 5.00 pm, be 13.
        Then the relative speed at 3.30pm, ie the average of the speeds at 3.00 and 4.00 pm, is 25.
        The clock stopped an additional 13 / (25 – 12) = 13 / 12 hours after 4.30pm.
        And so the clock stopped at 5.35pm.

        Like

  • Unknown's avatar

    Jim Randell 1:57 pm on 15 December 2019 Permalink | Reply
    Tags:   

    Brainteaser 1771: Lottery logic 

    From The Sunday Times, 25th August 1996 [link]

    For his weekly flutter on the National Lottery my friend has to select six of the numbers between 1 and 49 inclusive. Last week he wrote his numbers in numerical order and noticed something which he thought would interest me.

    The first three numbers written in succession, with no gaps, formed a perfect square. The remaining three, similarly combined, formed another square. He suggested I try to deduce his six numbers.

    Fortunately I knew his largest number was even and that he always chose one single-digit number.

    Which numbers had he selected?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1771]

     
    • Jim Randell's avatar

      Jim Randell 1:58 pm on 15 December 2019 Permalink | Reply

      This Python program runs in 74ms.

      Run: [ @replit ]

      from itertools import product
      from enigma import (irange, nsplit, printf)
      
      # consider 5- and 6- digit squares
      (n5s, n6s) = (list(), list())
      for i in irange(102, 689):
        n = i * i
        # split the square into 3 2-digit numbers
        (a, b, c) = nsplit(n, 3, 100)
        # the numbers must be increasing, less than 50
        if not (a < b < c < 50): continue
        if a < 10:
          # the first set has exactly one 1-digit number
          if not (b < 10): n5s.append((a, b, c))
        else:
          # the second set ends with an even number
          if c % 2 == 0: n6s.append((a, b, c))
      
      # choose two groups of three
      for (n5, n6) in product(n5s, n6s):
        # are the groups in order?
        if not (n5[-1] < n6[0]): continue
        # output the numbers
        printf("{s}", s=n5 + n6)
      

      Solution: The numbers chosen are: 2, 13, 16, 21, 34, 44.

      We have: 21316 = 146², 213444 = 462².

      Like

    • GeoffR's avatar

      GeoffR 10:21 am on 16 December 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; var 1..9:J;
      var 1..9:K;
      
      var 10..49:BC = 10*B + C; 
      var 10..49:DE = 10*D + E;
      var 10..49:FG = 10*F + G;
      var 10..49:HI = 10*H + I;
      var 10..49:JK = 10*J + K;
      
      % Lottery numbers are A, BC, DE, FG, HI, and JK
      constraint all_different ([BC, DE, FG, HI, JK]);
      
      % He wrote his numbers in numerical order
      constraint increasing([BC, DE, FG, HI, JK]);
      
      % Largest lottery number was even
      constraint JK mod 2 == 0;
      
      % Two perfect squares are ABCDE and FGHIJK
      var 10000..99999: ABCDE = 10000*A + 1000*B + 100*C + 10*D + E;
      
      var 100000..999999: FGHIJK = 100000*F + 10000*G
      + 1000*H + 100*I + 10*J + K;
      
      predicate is_sq(var int: y) =
        let {
           var 1..ceil(sqrt(int2float(ub(y)))): z
        } in z*z = y;
         
      % Split the six lottery numbers into two perfect squares
      constraint is_sq(ABCDE) /\ is_sq(FGHIJK);
      
      solve satisfy;
      
      output [ "Six Lottery numbers were " ++ show(A) ++ 
      ", " ++ show(BC) ++ ", " ++ show(DE)
      ++ ", " ++ show(FG) ++ ", " ++ show(HI) ++ 
      " and " ++ show(JK) ];
      
      % Six Lottery numbers were 2, 13, 16, 21, 34 and 44
      % % time elapsed: 0.03 s
      % ----------
      % ==========
      
      
      

      Like

      • John Crabtree's avatar

        John Crabtree 4:39 pm on 18 December 2019 Permalink | Reply

        The second square must end in 44 (sq. root = 362 + 50x or 338 + 50x), 36 (sq. root = 344 + 50x or 356 + 50x), or 24 (sq. root = 332 + 50x or 318 + 50x). By use of a calculator, the second square = 213444
        Then the first square must end in 16 (sq. root = 104 + 50x or 146 + 50x). Again by use of a calculator, the first square = 21316.
        And so the six numbers are 2, 13, 16, 21, 34 and 44.

        Like

  • Unknown's avatar

    Jim Randell 10:27 am on 8 December 2019 Permalink | Reply
    Tags:   

    Brainteaser 1770: Magic spell 

    From The Sunday Times, 18th August 1996 [link]

    Marvo uses a prearranged pack of cards to perform the following trick. Holding the pack face downwards, one by one he would take a card from the top and place it on the bottom, calling out a letter each time so as to spell:

    A, C, E, [the next card is an ace, which is placed on the table]
    T, W, O, [next card is a 2]
    T, H, R, E, E, [next card is a 3]

    J, A, C, K, [next card is a Jack]
    Q, U, E, E, N, [next card is a Queen]
    K, I, N, G, [next card is a King]
    A, C, E, [next card is an ace]
    T, W, O, [next card is a 2]

    Once he had spelt out the name of the card he would remove the next card from the pack, turn it over and place it face up on the table. Of course it was always the card which he had just spelt out.

    In this way he worked through the clubs, then the hearts, then the diamonds and finally the spades, finishing with just the King of spades in his hand.

    One day his disgruntled assistant sabotaged his act by secretly cutting the pack. However the first card which Marvo turned over was still an ace, and the the second card was still a two.

    What was the next card Marvo turned over?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1770]

     
    • Jim Randell's avatar

      Jim Randell 10:28 am on 8 December 2019 Permalink | Reply

      We can construct the initial configuration of the pack by starting with a pack of blank cards numbered in order from 1 to 52, and then performing the trick, but when we turn over one of the blank cards we write the appropriate value and suit on the card and continue until the end of the trick. We can then use the numbers to put the pack back into the desired order.

      We can then look through the pack for an ace followed 4 cards later by a two, and then we are interested what card occurs 6 cards after that.

      This Python program runs in 70ms.

      Run: [ @repl.it ]

      from enigma import irange, printf
      
      # words for each value
      word = {
        'A': 'ACE', '2': 'TWO', '3': 'THREE', '4': 'FOUR', '5': 'FIVE',
        '6': 'SIX', '7': 'SEVEN', '8': 'EIGHT', '9': 'NINE', 'X': 'TEN',
        'J': 'JACK', 'Q': 'QUEEN', 'K': 'KING',
      }
      
      # the positions in the pack
      pack = list(irange(0, 51))
      
      # map position -> value + suit
      m = dict()
      
      # go through the suits
      for s in "CHDS":
        # and then the values in each suit
        for v in "A23456789XJQK":
          # apply the operation the appropriate number of times
          for x in word[v]:
            pack.append(pack.pop(0))
          # reveal and discard the top card
          n = pack.pop(0)
          assert n not in m
          # record that card at this position
          m[n] = v + s
      
      # advance by counting value v
      advance = lambda k, v: (k + len(word[v]) + 1) % 52
      
      # look for an ace...
      for (k1, v1) in m.items():
        if v1[0] != 'A': continue
        # but not not the ace we are expecting
        if v1 == 'AC': continue
        # ... followed by a 2 ...
        k2 = advance(k1, '2')
        v2 = m[k2]
        if v2[0] != '2': continue
        # ... and what is the next card?
        k3 = advance(k2, '3')
        v3 = m[k3]
        printf("@{k1}: {v1} -> @{k2}: {v2} -> @{k3}: {v3}")
      

      Solution: The third card turned over is the three of diamonds.

      After that the trick would go awry. The next card turned over is not a 4, it is 8♦.

      The original layout of the pack is:

      After the pack is cut 4♣ is at the top (as highlighted in the diagram), after counting out A, C, E we get A♠, and then T, W, O gets 2♥, and then T, H, R, E, E gets 3♦.

      Like

  • Unknown's avatar

    Jim Randell 8:11 am on 24 November 2019 Permalink | Reply
    Tags:   

    Brainteaser 1766: House squares 

    From The Sunday Times, 21st July 1996 [link]

    There is an even number of houses in my road, numbered consecutively from 1 upwards, with the odd numbers on one side and the even numbers on the other.

    My neighbour’s son was practising with his new calculator. He found the sum of the squares of all the house numbers on one side of the road and subtracted it from the sum of the squares of all the house numbers on the other side of the road. The digits in his answer were all the same.

    Noticing that two of the houses displayed “For Sale” signs he decided to carry out a second calculation omitting those two houses. This gave an answer 50% higher than the first.

    Which two houses are for sale?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1766]

     
    • Jim Randell's avatar

      Jim Randell 8:12 am on 24 November 2019 Permalink | Reply

      This Python program runs in 70ms.

      Run: [ @repl.it ]

      from enigma import seq_all_same, nsplit, irange, div, subsets, printf
      
      # generate the difference between the sum of the even and odd squares up to n
      def generate():
        # sums of squares
        n = d = 0
        while True:
          n += 1
          d -= n * n
          n += 1
          d += n * n
          yield (n, d)
      
      # find solutions to the puzzle
      def solve():
        # look at differences for increasing even n
        for (n, d) in generate():
          # the difference should be a repdigit
          if not seq_all_same(nsplit(d)): continue
          # the second answer is 50% higher
          diff = div(d, 2)
          if diff is None: continue
      
          # look for the house numbers for sale p, q
          for (p, q) in subsets(irange(1, n), size=2):
            delta = sum([-1, 1][x % 2] * x * x for x in (p, q))
            if abs(delta) == diff:
              yield (p, q, n, d, d + diff)
      
      # we only need the first solution
      for (p, q, n, d, d2) in solve():
        printf("for sale = {s} [{n} houses; difference = {d} -> {d2}]", s=(p, q))
        break
      

      Solution: The two houses for sale are 14 and 23.

      There are 36 houses in the street.

      The result of the first calculation is 666.

      The result of the second calculation is 999.

      The difference between the sums of the squares of the first n even numbers and the first n odd numbers can be expressed:

      D(n) = n (2n + 1)

      Which allows a slightly shorter program than generating the differences constructively.

      Like

  • Unknown's avatar

    Jim Randell 9:57 am on 17 November 2019 Permalink | Reply
    Tags: by: Conor Henderson   

    Brainteaser 1757: Enigma variations 

    From The Sunday Times, 19th May 1996 [link]

    I recently joined Enigma, the international club for puzzle-solvers. When I received my membership card I noticed that my membership number was a six-figure number and that its digits could be rearranged to make three consecutive two-figure numbers.

    I also noticed that its six digits could be rearranged to form two consecutive three-figure numbers.

    Furthermore, no one with a lower six-figure membership number could make the same claims.

    What is my membership number?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1757]

     
    • Jim Randell's avatar

      Jim Randell 8:51 am on 19 November 2019 Permalink | Reply

      We can examine sequences of 3 consecutive 2-digit numbers (there are only 88 of them), and look for ones whose digits can be rearranged to form 2 consecutive 3-digit numbers. Each of these produces a collection of 6-digit membership numbers, and we can choose the smallest of these.

      This Python program runs in 135ms.

      Run: [ @repl.it ]

      from enigma import irange, tuples, multiset, nsplit, subsets, nconcat, Accumulator, printf
      
      # collect the digits from a sequence of numbers
      digits = lambda ns: multiset.from_seq(*(nsplit(n) for n in ns))
      
      # turn digits ds into n consecutive k-digit numbers
      def consecutive(ds, n, k):
        # extract the first k-digit number
        for s in subsets(ds, size=k, select="mP"):
          if s[0] == 0: continue
          # make the sequence of consecutive numbers
          s = nconcat(s)
          ss = tuple(irange(s, s + n - 1))
          # does it use the same digits?
          if digits(ss) == ds:
            yield ss
      
      # find the smallest number
      r = Accumulator(fn=min)
      
      # consider 3 consecutive 2-digit numbers
      for n2s in tuples(irange(10, 99), 3):
        ds = digits(n2s)
      
        # can the digits be rearranged to form 2 consecutive 3-digit numbers?
        n3s = list(consecutive(ds, 2, 3))
        if not n3s: continue
      
        # construct the smallest possible 6 digit number from the digits
        n = sorted(ds)
        # but leading zeros aren't allowed
        if n[0] == 0:
          # bring the first non-zero digit forward
          n.insert(0, n.pop(next(i for (i, x) in enumerate(n) if x > 0)))
        n = nconcat(n)
      
        printf("[{n:06d} -> {n2s} -> {n3s}]")
        r.accumulate(n)
      
      # output solution
      printf("membership number = {r.value:06d}")
      

      Solution: Your membership number is: 102222.

      The six digits of 102222 can be rearranged as (20, 21, 22) and also (220, 221).

      The largest such number is 999987:

      999987 → (97, 98, 99), (997, 998)

      There are 19 viable sequences of 3 consecutive 2-digit numbers, which give a total of 1195 candidate membership numbers.

      If leading zeros were allowed (which would not be uncommon for membership numbers) the lowest viable membership number would be 012222 (and there would be 1350 candidate numbers).

      Like

  • Unknown's avatar

    Jim Randell 9:06 am on 17 November 2019 Permalink | Reply
    Tags:   

    Brainteaser 1747: Lottery charges 

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

    Chargealot are having a new set of lottery balls made. They are going to be painted with numbers from 1 (not 01) to 49. The painter decides that this is one chance to make a fortune from the lottery and so he charges accordingly. He divides the digits into two types and charges a certain whole number of pounds for painting each digit of one type (each time it occurs) and a different whole number of pounds for all the other digits (each time they occur). Both charges are more than £50 but less than £100.

    To make the cost sound reasonable, instead of quoting a price for the whole set he quoted the average price per ball. Of course some balls cost less than average, and some balls cost more, but just one ball’s price was equal to the average.

    What were his two charges per digit?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1747]

     
    • Jim Randell's avatar

      Jim Randell 9:07 am on 17 November 2019 Permalink | Reply

      We can divide the digits from 0-9 into two sets, “type A” and “type B” with associated costs a and b.

      There are 9 single digit numbers and 40 2-digit numbers, so the 49 numbers use 89 digits in total.

      If, in total, there are nA type A digits and nB type B digits then we have:

      nA + nB = 89
      T = a × nA + b × nB = 49 × m

      where T is the total cost and m is the average cost per ball, and only one of the balls can cost the average amount.

      This Python program runs in 158ms.

      Run: [ @repl.it ]

      from collections import defaultdict
      from enigma import subsets, diff, irange, nsplit, div, printf
      
      # place 0 in set A and choose some other digits to go in set B
      for B in subsets(irange(1, 9), min_size=1):
        A = diff(irange(0, 9), B)
      
        # group the numbers by (A, B) usage
        d = defaultdict(list)
        nA = 0
        for n in irange(1, 49):
          # count the A and B digits
          k = [0, 0]
          for x in nsplit(n):
            k[x in B] += 1
          d[tuple(k)].append(n)
          nA += k[0]
        nB = 89 - nA
      
        # find a number in a class by itself
        for ((i, j), vs) in d.items():
          if len(vs) != 1: continue
      
          # find costs for the digits in A and B
          for a in irange(51, 99):
            b = div(a * (49 * i - nA), nB - 49 * j)
            if b is None or b < 51 or b > 99: continue
      
            # check none of the other groups cost the same as the mean
            m = a * i + b * j
            if any(a * x + b * y == m for (x, y) in d.keys() if not(x == i and y == j)): continue
      
            # output solution
            printf("cost = ({a}, {b}), digits = ({A}, {B}); mean = {m}, number = {vs[0]}")
      

      Solution: Each digit costs £ 74 or £ 83.

      The ball that costs the mean amount is one of the repeated digit balls, i.e. 11, 22, 33, 44. It costs £ 148 (i.e. 2× £ 74).

      The digit used twice on the mean ball is the only digit that costs £ 74, all the other digits cost £ 83.

      The total cost for all the balls is therefore £ 7252.

      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