Tagged: by: Richard Beetham Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 9:03 am on 19 September 2021 Permalink | Reply
    Tags: by: Richard Beetham   

    Brain-Teaser 43: [Golf match] 

    From The Sunday Times, 14th January 1962 [link]

    Brown came into the clubhouse after his match with Jones. “We were all square after nine holes”, he said, “when Jones suggested that we should play for a small side-stake on the winning of the tenth hole, double the stake on the eleventh, double again on the twelfth, and so on. I agreed. We didn’t halve any of the next nine holes, the match was decided on the eighteenth green, and I found that I had won eleven shillings and ninepence”. We asked him who won the match. “Work it out”, said Brown.

    Who won the match, which of the last nine holes did Brown win, and what was the side-stake on the tenth hole?

    This puzzle was originally published with no title.

    [teaser43]

     
    • Jim Randell's avatar

      Jim Randell 9:03 am on 19 September 2021 Permalink | Reply

      B and J were equal after the first 9 holes (i.e. 4.5 holes each). And each won 4 of the next 8 holes, so that the match was decided on the 18th hole.

      If the stake on the 10th hole was k, then it increases in powers of 2, i.e. k, 2k, 4k, 8k, 16k, …, 256k.

      In order to come out on top B must have won the 256k hole (as the remaining holes sum to 255k), and so B won the match.

      In binary, B’s stake multiplier has 5 bits and is between 100001111 (= 271) and 111110000 (= 496), and J’s multiplier is (111111111 − B).

      In order for B to win 11s + 9d = 141d the stake on the 10th hole is 141 / (B − J), and I assume the stake is some sensible amount (i.e. a multiple of 1/4 d).

      This Python program runs in 53ms.

      from enigma import (bit_permutations, div, irange, printf)
      
      # choose B's stake multiplier
      for B in bit_permutations(0b100001111):
        J = 0b111111111 - B
        k = div(564, B - J)
        if k:
          hs = list(h + 10 for h in irange(0, 8) if B & (1 << h))
          printf("holes = {hs}; stake @ 10 = {k:g}d", k=0.25 * k)
        if B == 0b111110000: break
      

      Solution: Brown won the match. Brown won the 10th, 11th, 12th, 14th, 18th holes. The stake on the 10th hole was 3d.

      The holes Brown won give: (1 + 2 + 4 + 16 + 256)k = 279k

      And the holes Brown lost give: (8 + 32 + 64 + 128)k = 232k

      The difference is: 279k − 232k = 47k, so: k = 141d / 47 = 3d

      Like

    • Hugh Casement's avatar

      Hugh Casement 10:14 am on 19 September 2021 Permalink | Reply

      To bring it up to date a bit, he won £2.35
      — though when we compare (for example) the cost of sending a letter then and now I feel an equivalent initial stake would be quite a bit more than 5p.

      Like

    • Frits's avatar

      Frits 5:52 pm on 4 October 2021 Permalink | Reply

        
      from enigma import SubstitutedExpression, div
      
      # the alphametic puzzle 
      p = SubstitutedExpression(
        [
         # Brown won 4 holes on holes 10-17
         "sum([A, B, C, D, E, F, G, H]) == 4",
         # Brown won the last hole
         "I = 1",
         # Brown's profit (141 pence) is a multiple of the stake
         "div(141, sum([2 ** i if x else -1 * 2 ** i \
              for i, x in enumerate([A, B, C, D, E, F, G, H, I])]))",
        ],
        base=2,
        answer="(A, B, C, D, E, F, G, H, I), \
               sum([2 ** i if x else -1 * 2 ** i \
                   for i, x in enumerate([A, B, C, D, E, F, G, H, I])])",
        verbose=0,
        distinct="",
      )
      
      # print answer
      for (_, ans) in p.solve():
        print(f"Brown won the match and the holes "
              f"{[i + 10 for i, x in enumerate(ans[0]) if x]}"
              f" with side-stake of {141 // ans[1]} pence")
      

      Like

  • Unknown's avatar

    Jim Randell 10:27 am on 17 November 2020 Permalink | Reply
    Tags: by: Richard Beetham   

    Brain-Teaser 13: [Fill out the grid] 

    From The Sunday Times, 28th May 1961 [link]

    The numbers 1 to 9, in any order and using each once only, are to be placed one at a time in the nine squares A to J. As each number replaces a letter in a square, any numbers standing at that moment in adjacent squares (left, right, up or down, but not diagonally) are to be multiplied by three.

    Thus, if we decided to begin with 4 in A, then 9 in E, 7 in B and 2 in D, etc., we should have:

    and so on. On completion, the nine final numbers are added together to find the score.

    There are obviously 81 ways of making the first move, and there are 131,681,894,400 ways of completing the array; yet the number of possible scores in quite small.

    What is the smallest possible score?

    This puzzle was originally published with no title.

    [teaser13]

     
    • Jim Randell's avatar

      Jim Randell 10:28 am on 17 November 2020 Permalink | Reply

      We can drastically reduce the number of possibilities we have consider:

      When the game is played the squares are filled out in a particular order. If, when we play the game, instead of filling in numbers we just note how many times the value in each particular square is trebled, then at the end we can find the minimum score for that particular ordering of squares by assigning 9 to the square that is trebled the fewest number of times (i.e. the final square filled out), 8 to the next lowest number of treblings, and so on until 1 is assigned to the square with the largest number of treblings.

      This Python program considers all possible orderings for filling out the squares. It runs in 420ms.

      Run: [ @repl.it ]

      from enigma import grid_adjacency, subsets, irange, printf
      
      # numbers to fill out
      nums = list(irange(1, 9))
      
      # grid adjacency matrix
      adj = grid_adjacency(3, 3)
      
      # multipliers (for number of treblings)
      mul = [1, 3, 9, 27, 81]
      
      # find the minimal score for a ordering of squares
      def play(js):
        # initial grid
        grid = [None] * 9
        # place the numbers
        for j in js:
          # place the number
          grid[j] = 0
          # and increase adjacent counts
          for i in adj[j]:
            if grid[i] is not None:
              grid[i] += 1
        # determine the minimum score
        return sum(n * mul[k] for (n, k) in zip(nums, sorted(grid, reverse=1)))
      
      # choose an ordering for the squares, and find the minimum score
      r = min(play(js) for js in subsets(irange(9), size=len, select="P"))
      printf("min score = {r}")
      

      Solution: The smallest possible score is 171.

      One way of getting this total is:

      [ A, B, C ] [ D, E, F ] [ G, H, J ]
      [ 2, B, C ] [ D, E, F ] [ G, H, J ]
      [ 6, 3, C ] [ D, E, F, ] [ G, H, J ]
      [ 6, 9, 4 ] [ D, E, F ] [ G, H, J ]
      [ 6, 27, 4 ] [ D, 1, F ] [ G, H, J ]
      [ 18, 27, 4, ] [ 5, 3, F ] [ G, H, J ]
      [ 18, 27, 12 ] [ 5, 9, 6 ] [ G, H, J ]
      [ 18, 27, 12 ] [ 15, 9, 6 ] [ 7, H, J ]
      [ 18, 27, 12 ] [ 15, 27, 6 ] [ 21, 8, J ]
      [ 18, 27, 12 ] [ 15, 27, 18 ] [ 21, 24, 9 ] = 171

      We can make the program run faster by exploiting the symmetry of the grid. For example, for the first move, we only need to consider one corner square, one edge square and the central square. It does make the program longer though.

      Like

    • Frits's avatar

      Frits 11:02 am on 19 November 2020 Permalink | Reply

      The first part finds the minimum score for different kind of treblings under the condition that they add up to 12. It turns out this minimum can also be achieved by our number placing rules.

      I didn’t immediately see how I could check if a list [A,B,C,D,E,F,G,H,J] from the result can be achieved so I reused Jim’s code to find the first permutation which has a score equal to this minimum.

      from enigma import SubstitutedExpression, grid_adjacency, subsets
      
      # numbers to fill out
      nums = list(range(1, 10))
      
      # grid adjacency matrix
      adj = grid_adjacency(3, 3)
      
      # multipliers (for number of treblings)
      mul = [1, 3, 9, 27, 81]
      
      score = lambda li: sum(n * mul[k] 
                         for (n, k) in zip(nums, sorted(li, reverse=1)))
      
      # the alphametic puzzle
      p = SubstitutedExpression(
        [
        # if field x has adjacent fields x1...xn and k of them have already been set
        #
        # then k fields will now get trebled which previously didn't treble field x
        # and (n - k) fields will not get trebled now but later on will treble 
        # field x (n - k) times. So for every trebling there is an instance of 
        # non-trebling.
        #
        # adjacent field matrix;
        #
        #  2  3  2    sum of all elements is 24  
        #  3  4  3    half of them will not get trebled
        #  2  3  2
        "sum([A,B,C,D,E,F,G,H,J]) == 12", 
        ],
        answer="score([A,B,C,D,E,F,G,H,J]), A,B,C,D,E,F,G,H,J",
        digits=range(0, 5),
        env=dict(score=score),
        accumulate=min,  
        d2i={3 : "ACGJ", 4: "ACGJBDFH"},
        distinct="",
        verbose=0)   
        
      # solve the puzzle
      r = p.run()
      min = list(r.accumulate)[0]
      
      lst = []
      prt = ["A", "B", "C", "D", "E", "F", "G", "H", "J"]
      
      # check if this minimum can be achieved
      for js in subsets(range(9), size=len, select="P"):
        grid = [None] * 9
        # place the numbers
        for j in js:
          # place the number
          grid[j] = 0
          # and increase adjacent counts
          for i in adj[j]:
            if grid[i] is not None:
              grid[i] += 1
              
        if score(grid) == min:
          print("smallest possible score:", min, "\n\nexample:\n")
         
          # sort grid (descending)
          lst = sorted(grid, reverse=True)
         
          # print all the steps
          for i in range(9):  
            for k, j in enumerate(js):
              if j != i: continue
              g = grid[k]
              ind = lst.index(g) 
              lst[ind] = -1          # set to "processed"
              prt[k] = ind + 1       # set field
              
              # treble adjacent fields
              for m in adj[k]:
                if type(prt[m]) == int:
                  prt[m] *= 3
                
              print(f"{prt[:3]} {prt[3:6]} {prt[6:]}")
          break  # we only print one example
          
      # smallest possible score: 171
      #
      # example:
      #
      # [2, 'B', 'C'] ['D', 'E', 'F'] ['G', 'H', 'J']
      # [6, 3, 'C'] ['D', 'E', 'F'] ['G', 'H', 'J']
      # [6, 9, 4] ['D', 'E', 'F'] ['G', 'H', 'J']
      # [6, 27, 4] ['D', 1, 'F'] ['G', 'H', 'J']
      # [18, 27, 4] [5, 3, 'F'] ['G', 'H', 'J']
      # [18, 27, 12] [5, 9, 6] ['G', 'H', 'J']
      # [18, 27, 12] [15, 9, 6] [7, 'H', 'J']
      # [18, 27, 12] [15, 27, 6] [21, 8, 'J']
      # [18, 27, 12] [15, 27, 18] [21, 24, 9]    
      

      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