# Enigmatic Code

Programming Enigma Puzzles

## Enigma 238: Sort out your draws

From New Scientist #1384, 17th November 1983 [link]

In our local football league the six teams, Algols, Basics, Computers, Digitals, Electronics and Fortrans, each played each other once this season and the end-of-season league table has just been published. The teams finished in alphabetical order with no two teams scoring the same total number of points. We work on the system of 3 points for a win and 1 point for a draw. Just knowing each of the teams’ total points, and the fact that during the season there had been at least twice as many draws as wins, enabled me to work out the result of each match.

Someone beat Basics. Which team (or teams)? And which team(s) beat Fortrans?

[enigma238]

### One response to “Enigma 238: Sort out your draws”

1. Jim Randell 17 November 2014 at 8:18 am

This Python program uses the Football() class from the enigma.py library. It runs in 5.5s, so it’s not particularly elegant or particularly fast.

```from collections import defaultdict
from enigma import Football, printf

football = Football(games='wdl', points={ 'w': 3, 'd': 1 })

r = defaultdict(list)

# matches for A
for (AB, AC, AD, AE, AF) in football.games(repeat=5):
A = football.table([AB, AC, AD, AE, AF], [0, 0, 0, 0, 0])

# remaining matches for B
for (BC, BD, BE, BF) in football.games(repeat=4):
B = football.table([AB, BC, BD, BE, BF], [1, 0, 0, 0, 0])
if not(A.points > B.points): continue

# remaining matches for C
for (CD, CE, CF) in football.games(repeat=3):
C = football.table([AC, BC, CD, CE, CF], [1, 1, 0, 0, 0])
if not(B.points > C.points): continue

# remaining matches for D
for (DE, DF) in football.games(repeat=2):
D = football.table([AD, BD, CD, DE, DF], [1, 1, 1, 0, 0])
if not(C.points > D.points): continue

# remaining match
for EF in football.games():
E = football.table([AE, BE, CE, DE, EF], [1, 1, 1, 1, 0])
F = football.table([AF, BF, CF, DF, EF], [1, 1, 1, 1, 1])
if not(D.points > E.points > F.points): continue

# overall there are at least twice as many drawn matches as won matches
s = (AB, AC, AD, AE, AF, BC, BD, BE, BF, CD, CE, CF, DE, DF, EF)
n = s.count('d')
if n < 10: continue

r[(A.points, B.points, C.points, D.points, E.points, F.points)].append(s)

printf("BC={BC} BD={BD} BE={BE} BF={BF}")
printf("CD={CD} CE={CE} CF={CF}")
printf("DE={DE} DF={DF}")
printf("EF={EF}")
printf("A={A}")
printf("B={B}")
printf("C={C}")
printf("D={D}")
printf("E={E}")
printf("F={F}")
printf()

# examine the possibilities
for (k, v) in r.items():
if len(v) != 1: continue

(AB, AC, AD, AE, AF, BC, BD, BE, BF, CD, CE, CF, DE, DF, EF) = v[0]

# find teams that beat B
bs = list(t for (m, t, x) in zip([AB, BC, BD, BE, BF], 'ACDEF', 'wllll') if m == x)
if not bs: continue

# find teams that beat F
fs = list(t for (m, t, x) in zip([AF, BF, CF, DF, EF], 'ABCDE', 'wwwww') if m == x)

printf("{k} => {v}")
printf("B lost to: {bs}", bs=' '.join(bs))
printf("F lost to: {fs}", fs=' '.join(fs))
printf()
```

Solution: Basics lost to Algols. Fortrans lost to Algols, Basics and Computers.