# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1005: Prime A v Square B

From New Scientist #2160, 14th November 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 between André and Boris went to a deciding fifth set. At the end of each set that André won, the total number of games played up to that point was always a prime number. At the end of each set that Boris won, the total number of games played up to that point was always a perfect square. No two sets contained the same number of games. If I told you the total number of games played at the end of one particular set you could deduce with certainty who won each individual set and what the score was in each set.

In giving the score of a tennis match, it is the convention to give the score in each set in order, always giving the match-winner’s score first, so that if the score is given as (say) 7-6, 5-7, 6-4, 3-6, 6-2, it shows that the two sets the match-winner lost were the second and fourth, won by the opponent by 7 games to 5 and 6 games to 3, respectively.

Using this convention, tell me who won my match and give me its score.

[enigma1005]

### One response to “Enigma 1005: Prime A v Square B”

1. Jim Randell 21 June 2019 at 8:51 am

This Python 3 program generates all possible matches that satisfy the conditions, and then looks at the total number of games in each match after each set is complete to find the set number which causes a match to be uniquely identified. It runs in 134ms.

Run: [ @repl.it ]

```from enigma import is_prime, is_square, irange, filter_unique, printf

# possible sets by total number of games
sets = dict((x + y, (x, y)) for (x, y) 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 ss
else:
# consider the next set
for (k, (x, y)) in sets.items():
if k in ks: continue
t2 = t + k
# set for A?
if (A < 2 or B == 2) and is_prime(t2):
yield from solve(t2, ss + [(x, y)], A + 1, B, ks + [k])
# set for B?
if (B < 2 or A == 2) and is_square(t2):
yield from solve(t2, ss + [(y, x)], A, B + 1, ks + [k])

# collect possible matches
ms = list(solve())

# now suppose we are told the total number of games after the k'th set
for k in irange(1, 5):

# total number of games up to the k'th set
fn = lambda ss: sum(a + b for (a, b) in ss[:k])

# find unique matches
(rs, _) = filter_unique(ms, fn, tuple)

# if there is only one match, that is our solution
if len(rs) == 1:
printf("[k={k}] {rs}")
```

Solution: A won the match 3-6, 6-2, 6-0, 6-7, 6-1.

A won 27 of the games, B won 16.

There are 7 possible matches that satisfy the conditions. Here are the scores (each set in the form A-B), along with the total number of games played after the 3rd set is complete

3-6, 1-6, 7-6, 6-2, 6-0 (29)
3-6, 1-6, 7-6, 6-2, 6-4 (29)
3-6, 1-6, 7-6, 6-2, 5-7 (29)
3-6, 1-6, 7-6, 7-5, 6-0 (29)
3-6, 1-6, 7-6, 7-5, 2-6 (29)
3-6, 6-2, 6-0, 6-7, 6-1 (23)
3-6, 6-2, 7-5, 1-6, 6-7 (29)

So the penultimate one is uniquely identified by the total number of games played after the 3rd set is complete.

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