# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1677: Six of one

From New Scientist #2843, 17th December 2011 [link]

Albion, Borough, City, Rangers and United have played a tournament in which each team played each of the other teams once. Two points were awarded for a win and one for a draw. In the final table the teams finished in alphabetical order, Albion with most points and United with fewest, no two teams having the same number of points. There was only one instance of two matches having the same score. No team scored more than 4 goals in any one match. In the course of the tournament each team scored 6 goals and conceded 6 goals.

Borough beat Albion 3-0. What were the scores in (a) Borough vs City and (b) Rangers vs United?

[enigma1677]

### 3 responses to “Enigma 1677: Six of one”

1. jimrandell 15 December 2011 at 12:01 am

The following Python script runs in 470ms.

```from itertools import product
from enigma import printf

scores = (
((0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)),
((0, 0), (1, 1), (2, 2), (3, 3), (4, 4)),
((1, 0), (2, 0), (3, 0), (4, 0), (2, 1), (3, 1), (4, 1), (3, 2), (4, 2), (4, 3))
)

(AB, sAB) = (0, (0, 3))
for (AC, AR, AU, BC, BR, BU, CR, CU, RU) in product((2, 1, 0), repeat=9):
A = sum((AB, AC, AR, AU))
B = sum((2-AB, BC, BR, BU))
C = sum((2-AC, 2-BC, CR, CU))
R = sum((2-AR, 2-BR, 2-CR, RU))
U = sum((2-AU, 2-BU, 2-CU, 2-RU))
if not(A > B > C > R > U): continue

for (sAC, sAR, sAU) in product(scores[AC], scores[AR], scores[AU]):
sA = [sAB, sAC, sAR, sAU]
s1 = set(sA)
if len(s1) < 3: continue
if tuple(map(sum, zip(*sA))) != (6, 6): continue

for (sBC, sBR, sBU) in product(scores[BC], scores[BR], scores[BU]):
sB = [sBC, sBR, sBU]
s2 = s1.union(sB)
if len(s2) < 6: continue
sB.append(tuple(reversed(sAB)))
if tuple(map(sum, zip(*sB))) != (6, 6): continue

for (sCR, sCU) in product(scores[CR], scores[CU]):
sC = [sCR, sCU]
s3 = s2.union(sC)
if len(s3) < 8: continue
sC.extend((tuple(reversed(x)) for x in (sAC, sBC)))
if tuple(map(sum, zip(*sC))) != (6, 6): continue

for sRU in scores[RU]:
sR = [sRU]
s4 = s3.union(sR)
if len(s4) != 9: continue
sR.extend((tuple(reversed(x)) for x in (sAR, sBR, sCR)))
if tuple(map(sum, zip(*sR))) != (6, 6): continue

sU = [tuple(reversed(x)) for x in (sAU, sBU, sCU, sRU)]
if tuple(map(sum, zip(*sU))) != (6, 6): continue

printf("BvC={sBC} RvU={sRU} [AvB={sAB} AvC={sAC} AvR={sAR} AvU={sAU} BvR={sBR} BvU={sBU} CvR={sCR} CvU={sCU}]")
```

Solution: (a) Borough 0 – City 0, (b) Rangers 3 – United 1.

2. jimrandell 16 December 2011 at 10:25 am

This version runs in 90ms. It’s the same code, but instead of generating the scores for each team’s 4th match and then rejecting the ones that don’t give 6 goals for and 6 goals against, we generate the score directly based on the other three matches, and then check that it’s a valid score.

```from itertools import product
from enigma import printf

# possible scores for lose [0 points], draw [1 point] and win [2 points]
scores = (
((0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)),
((0, 0), (1, 1), (2, 2), (3, 3), (4, 4)),
((1, 0), (2, 0), (3, 0), (4, 0), (2, 1), (3, 1), (4, 1), (3, 2), (4, 2), (4, 3))
)

(AB, sAB) = (0, (0, 3))
# work out the points
for (AC, AR, AU, BC, BR, BU, CR, CU, RU) in product((2, 1, 0), repeat=9):
A = sum((AB, AC, AR, AU))
B = sum((2-AB, BC, BR, BU))
C = sum((2-AC, 2-BC, CR, CU))
R = sum((2-AR, 2-BR, 2-CR, RU))
U = sum((2-AU, 2-BU, 2-CU, 2-RU))
if not(A > B > C > R > U): continue

for (sAC, sAR) in product(scores[AC], scores[AR]):
sAU = (6-sAB[0]-sAC[0]-sAR[0], 6-sAB[1]-sAC[1]-sAR[1])
if not sAU in scores[AU]: continue
s1 = set((sAB, sAC, sAR, sAU))
if len(s1) < 3: continue

for (sBC, sBR) in product(scores[BC], scores[BR]):
sBU = (6-sAB[1]-sBC[0]-sBR[0], 6-sAB[0]-sBC[1]-sBR[1])
if not sBU in scores[BU]: continue
s2 = s1.union((sBC, sBR, sBU))
if len(s2) < 6: continue

for sCR in scores[CR]:
sCU = (6-sAC[1]-sBC[1]-sCR[0], 6-sAC[0]-sBC[0]-sCR[1])
if not sCU in scores[CU]: continue
s3 = s2.union((sCR, sCU))
if len(s3) < 8: continue

sRU = (6-sAR[1]-sBR[1]-sCR[1], 6-sAR[0]-sBR[0]-sCR[0])
if not sRU in scores[RU]: continue
s4 = s3.union((sRU,))
if len(s4) != 9: continue

sU = (sAU, sBU, sCU, sRU)
if tuple(map(sum, zip(*sU))) != (6, 6): continue

printf("BvC={sBC} RvU={sRU} [AvB={sAB} AvC={sAC} AvR={sAR} AvU={sAU} BvR={sBR} BvU={sBU} CvR={sCR} CvU={sCU}]")
```
3. martin 19 February 2013 at 7:12 am

I remember solving that one also using Python. My solution was very heavy.
I will dig in my “enigma library to compare.
Have a nice day

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