Enigmatic Code

Programming Enigma Puzzles

Enigma 208: Snooker doubles

From New Scientist #1354, 21st April 1983 [link]

In a recent frame at a snooker match the were no penalty points and after each of the 15 reds was potted a colour was potted (each of the six colours following two or three of the reds). The surprising thing about the result was that the winner’s total score was twice that of the loser, and yet they had both potted the same total number of balls.

What was the loser’s total and how many reds, how many yellows, how many greens, how many browns, how many blues, how many pinks and how many blacks did he pot?

(In snooker the potting of a red is followed by the potting of one of the other colours, the red remaining down but the other colour returning to the table. After 15 such events the remaining six colours are potted in the order stated above, reds are worth 1 point and the rest 2-7 in the order stated above).



6 responses to “Enigma 208: Snooker doubles

  1. Jim Randell 21 July 2014 at 7:53 am

    This Python program runs in 238ms.

    from collections import defaultdict, Counter
    from itertools import combinations
    from enigma import irange, subsets, flatten, printf
    # possible scores for potting the final six colours
    final = defaultdict(list)
    for s in subsets((2, 3, 4, 5, 6, 7)):
    # with the reds the colours are potted 15 times, and each is potted 2
    # or 3 times.
    # if each is potted twice that is only 12 colours, so 3 of the colours
    # are potted 3 times.
    # choose colours that are potted 3 times
    for (i1, i2, i3) in combinations(irange(2, 7), 3):
      # how many times is each ball potted?
      ps = [0, 0, 2, 2, 2, 2, 2, 2]
      ps[i1] = ps[i2] = ps[i3] = 3
      # determine the total number of points
      t = 42 + sum(i * n for (i, n) in enumerate(ps))
      # winners score = 2x, losers score = x
      (x, r) = divmod(t, 3)
      if r > 0: continue
      # what colours go with the reds
      colours = flatten([i] * n for (i, n) in enumerate(ps))
      # choose the number of reds for the loser
      for n in irange(0, 15):
        # choose the colours to go with the reds
        for cs in combinations(colours, n):
          # score so far
          s = n + sum(cs)
          if s > x: continue
          # find possibilities for the remaining score
          for f in final[x - s]:
            # and check 18 balls are potted
            if n + len(cs) + len(f) == 18:
              # count the colours
              c = Counter(cs) + Counter(f)
              printf("loser scores {x} points, reds = {n}, colours = {c}")

    Solution: The loser scored 36 points, and potted 8 reds, 4 yellows, 4 greens, 2 browns, and none of the other colours.

    Along with the 8 reds the loser potted 3 yellows, 3 greens and 2 browns, and then in the final clearing of the colours also potted the yellow and the green.

    It follows that the winner scored 72 points, potting 7 reds and in the final clearing of the colours the brown, blue, pink and black, meaning that the colours potted with the 7 reds made a total of 43 points. One way to achieve this would be 6 pinks and 1 black. But as Brian points out below the actual colours potted is determined by the program – it is 2 blues, 2 pinks and 3 blacks.

  2. Brian Gladman 21 July 2014 at 9:55 pm
    from itertools import combinations, product
    # values for the 'coloured' balls
    values = range(2, 8)
    # the numbers of the balls that are potted three times
    for c1, c2, c3 in combinations(range(6), 3):
      # compose the number of each colour potted
      nc = [2] * 6
      nc[c1] = nc[c2] = nc[c3] = 3
      # ther winner scores twice what the loser scores
      total = 42 + sum(a * b for a, b in zip(nc, values))
      loser, rem = divmod(total, 3)
      if rem:
      # now consider all possible numbers of the six coloured balls 
      for ncols in product(*(range(nc[i] + 1) for i in range(6))):
        # the number of balls potted by the loser and their sum
        n, c = sum(ncols), sum(a * b for a, b in zip(ncols, values))
        # each player pots 18 balls, so the number of 'final' colours potted is
        # 18 less twice the number of colours potted with reds (and 6 or less)
        final_no = 18 - 2 * n
        if 0 <= final_no <= 6:
          # try combinations of this number of 'colours' to make the fianl score
          for rest in combinations(range(6), final_no):
            if n + c + sum(values[x] for x in rest) == loser:
              nt = tuple(n + 1 if i in rest else n for i, n in enumerate(ncols)) 
              print('loser:  {} points, {} reds, colours {}.'.format(loser, n, nt))
              # calculate values for the winner
              n2, r2 = 15 - n, set(range(6)) - set(rest)         
              ncolw = [(b - c) for b, c in zip(nc, ncols)]
              nt2 = tuple(n + 1 if i in r2 else n for i, n in enumerate(ncolw)) 
              print('winner: {} points, {} reds, colours {}.'.format(2 * loser, n2, nt2))

    My results are:

    loser: 36 points, 8 reds, colours (4, 4, 2, 0, 0, 0).
    winner: 72 points, 7 reds, colours (0, 0, 1, 3, 3, 4).

    I don’t think there is a free choice of how the winners score is made up since any colours that the loser doesn’t pot are potted by the winner.

    • Jim Randell 21 July 2014 at 11:46 pm

      You’re right of course. The solution tells you the way the winner made his 43 points from the colours potted along with the 7 reds – 2 blues, 2 pinks and 3 blacks.

  3. Hugh Casement 15 August 2014 at 8:22 pm

    Jim, it seems the winner potted only 14 balls before the ‘clearing’. So is your solution valid?

    • Jim Randell 18 August 2014 at 8:21 pm

      Hi Hugh,

      I’m not quite sure what your objection is to the solution I gave.

      The solution that my program finds is as follows:

      The loser pots 8 of the reds, and after each red one colour to make 3 yellows, 3 greens and 2 browns in total.

      The winner pots 7 of the reds, and after each red one colour to make 2 blues, 2 pinks and 3 blacks in total.

      So, in the clearing of the reds each colour is potted 2 or 3 times, as required.

      Then in the final clearing of the colours the loser pots the yellow and the green, and the winner pots the remaining brown, blue, pink and black.

      Each player has potted 18 balls, and the winner scores 72 points, the loser scores 36, as required.

      I’m not a snooker fan, but I think that there could be many matches that correspond to this, for example:

      1. The winner pots 7 reds and 7 colours.
      2. The loser pots 8 red and 8 colours, then starts to clear the colours and pots the yellow and the green.
      3. The winner pots the remaining four colours.

      • Hugh Casement 19 August 2014 at 6:57 am

        I was misled by the statement “After 15 such events the remaining six colours are potted …”. Susan Denham’s explanation was not very clear for those who have never watched a game of snooker. 7 reds and 7 colours appears to make only 14 “events”; I now see she meant 15 reds between the two players.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: