Enigmatic Code

Programming Enigma Puzzles

Enigma 966: Prime tennis

From New Scientist #2121, 14th February 1998 [link]

At tennis a set is won by the first player to win 6 games, except that if it goes to 5 games all it is won either 7 games to 5 or 7 games to 6. (As far as this puzzle is concerned this applies even to the final set).

The match that we are considering went to 5 sets and no two sets contained the same number of games. At the end of each set the total number of games played up to that point was always a prime number. From this information the score in one or more of the five sets can be deduced with certainty.

Which sets had a score that can be deduced with certainty, and what was the score in each of the sets concerned?


One response to “Enigma 966: Prime tennis

  1. Jim Randell 3 April 2020 at 8:35 am

    See also Enigma 1005, also set by Richard England.

    I adapted the program I wrote for Enigma 1005.

    The following Python 3 program runs in 95ms.

    Run: [ @repl.it ]

    from enigma import is_prime, irange, ordered, printf
    # possible sets by total number of games
    sets = dict((a + b, (a, b)) for (a, b) in [
      (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (7, 5), (7, 6)
    # find matches that satisfy the conditions
    # t = total number of games played so far
    # ss = list of sets (a, b)
    # A = number of sets won by A
    # B = number of sets won by B
    # ks = keys already used
    def solve(t=0, ss=[], A=0, B=0, ks=[]):
      # are we done?
      if A + B == 5:
        yield (A, B, ss)
        # consider the next set
        for (k, (x, y)) in sets.items():
          if k in ks: continue
          tk = t + k
          if is_prime(tk):
            # set for A?
            if A < 2 or B == 2:
              yield from solve(tk, ss + [(x, y)], A + 1, B, ks + [k])
            # set for B?
            if B < 2 or A == 2:
              yield from solve(tk, ss + [(y, x)], A, B + 1, ks + [k])
    # accumulate the outcomes of each numbered set
    r = dict((i, set()) for i in irange(1, 5))
    for (A, B, ss) in solve():
      if not(A > B): continue # only consider cases where A wins
      for (k, (x, y)) in enumerate(ss, start=1):
        r[k].add(ordered(x, y))
    # find outcomes with only one possible value
    for k in sorted(r.keys()):
      vs = r[k]
      if len(vs) == 1:
        for v in vs:
          printf("set {k} -> {v[::-1]}")

    Solution: The outcomes of sets 1 and 4 are known. Set 1 is won 6-1. Set 4 is won 6-2.

    It turns out that in order for there to be a solution to the puzzle we have to report the scores in each set as an unordered pair. So, if a match went: 6-1, 0-6, 6-4, 2-6, 7-5, then we consider the scores 6-1, 6-0, 6-4, 6-2, 7-5.

    So we cannot tell if the match winner or the opponent won sets 1 or 4.

Leave a Reply to Jim Randell Cancel reply

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: