Enigmatic Code

Programming Enigma Puzzles

Enigma 1327: At the crucible

From New Scientist #2486, 12th February 2005

In the final of the World Snooker Championships the winner is the first player to win 18 frames. A frame cannot be halved. The final is divided into four sessions, with eight games in each of the first three session (unless the match is won before the end of the third session) and as many frames as are necessary to decide the winner in the fourth session.

When Davies beat Whyte in the final the match did go into the fourth session. The number of frames won by Davies in each session and the number of frames won by Whyte in each session were eight different numbers. In the fourth session Whyte won more frames than Davies. If I tell you how many frames Davies won in that session you could deduce with certainty how many Whyte won in it.

How many frames did each player win (Whyte’s score first) in (a) the fourth session, (b) the other session in which Whyte won more frames than Davies?

[enigma1327]

Advertisements

One response to “Enigma 1327: At the crucible

  1. Jim Randell 4 May 2014 at 9:09 am

    This Python program runs in 33ms.

    from collections import defaultdict
    from itertools import combinations
    from enigma import irange, flatten, printf
    
    # accumulate possible scores by the final frame scores
    r = defaultdict(lambda: defaultdict(list))
    
    # the first 3 sessions must go to 8 frames, and D must have different
    # scores in each (but we don't know the order they come in)
    for (D1, D2, D3) in combinations(irange(0, 8), 3):
      (W1, W2, W3) = (8 - D1, 8 - D2, 8 - D3)
      if len(set((D1, D2, D3, W1, W2, W3))) != 6: continue
    
      # D is the first to 18, but loses the final session
      D4 = 18 - (D1 + D2 + D3)
      if not(0 < D4 < 6) or D4 in (W1, D1, D2, W2, D3, W3): continue
      for W4 in irange(D4 + 1, 11 - D4):
        if W1 + W2 + W3 + W4 > 18 or W4 in (W1, D1, D2, W2, D3, W3, D4): continue
        r[D4][W4].append((D1, W1, D2, W2, D3, W3))
        printf("[{D1}-{W1} {D2}-{W2} {D3}-{W3} {D4}-{W4}]")
    
    # find final sesson scores for D that only give one possible score for W
    for (D4, vs) in r.items():
      if len(vs) != 1: continue
      for (W4, ss) in vs.items():
        # look at the possible scorelines
        for s in ss:
          (D1, W1, D2, W2, D3, W3) = s
          printf("sessions 1-3: {D1}-{W1}/{D2}-{W2}/{D3}-{W3}, session 4: {D4}-{W4}")
    

    Solution: (a) Whyte won the fourth session 6-4; (b) Whyte won another session 7-1.

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: