# Enigmatic Code

Programming Enigma Puzzles

## Enigma 185: League reform

From New Scientist #1330, 4th November 1982 [link]

Our local league has four teams, each of whom plays each other once each season. The league table at the end of last season is (with each digit replaced consistently by a letter) partly shown below. This was on the old scheme of two points for a win and one for a draw, and the teams are shown in order of merit (with goal difference deciding the order in the event of ties on points).

In order to decide whether to switch to the new scheme of three points for a win and one for a draw, we’ve worked out what the table would look like under this new scheme, and that is partly shown too.

What were the scores in the six matches? (In the order AvB, AvC, AvD, BvC, BvD, CvD).

[enigma185]

### One response to “Enigma 185: League reform”

1. Jim Randell 20 April 2014 at 9:13 am

This Python program uses the Football() class from the enigma.py library. It runs in 69ms.

```from itertools import permutations
from enigma import irange, Football, is_pairwise_distinct, printf

# compare points / goal differences
def is_ordered(pX, pY, dX, dY):
return pX > pY or (pX == pY and dX > dY)

# single digits
digits = set(irange(0, 9))

# 2 points / 3 points for a win scoring
football = Football(games='wdl', points={ 'w': 2, 'd': 1 })
football3 = Football(games='wdl', points={ 'w': 3, 'd': 1 })

# consider possible match outcomes
for (AB, AC, AD, BC, BD, CD) in football.games(repeat=6):
# compute the table
A = football.table([AB, AC, AD], [0, 0, 0])
B = football.table([AB, BC, BD], [1, 0, 0])
C = football.table([AC, BC, CD], [1, 1, 0])
D = football.table([AD, BD, CD], [1, 1, 1])
# check the points order
if not(C.points >= A.points >= B.points >= D.points): continue
# and the letter assignments
(P, Q, U) = (C.points, B.points, B.l)
if A.w != Q: continue
if not is_pairwise_distinct(P, Q, U): continue

# compute the table under the alternate rules
A3 = football3.table([AB, AC, AD], [0, 0, 0])
B3 = football3.table([AB, BC, BD], [1, 0, 0])
C3 = football3.table([AC, BC, CD], [1, 1, 0])
D3 = football3.table([AD, BD, CD], [1, 1, 1])
# check the points order
if not(A3.points >= C3.points >= B3.points >= D3.points): continue
# and the letter assignements
V = C3.points
if V in (P, Q, U): continue

# possible scorelines for C
for aC in digits:
for (sAC, sBC, sCD) in football.scores([AC, BC, CD], [1, 1, 0], Q, aC):

# possible scorelines for B
for fB in digits:
for (sAB, sBD) in football.scores([AB, BD], [1, 0], fB, U, [sBC], [0]):

# possible scorelines for A
for (R, S) in permutations(digits.difference([P, Q, U, V]), 2):
if not is_ordered(C.points, A.points, Q - aC, R - S): continue
if not is_ordered(A.points, B.points, R - S, fB - U): continue
if not is_ordered(A3.points, C3.points, R - S, Q - aC): continue
if not is_ordered(C3.points, B3.points, Q - aC, fB - U): continue
# determine goals for/against D
if T in (P, Q, U, V, R, S): continue
if not is_ordered(B.points, D.points, fB - U, T - aD): continue
if not is_ordered(B3.points, D3.points, fB - U, T - aD): continue

printf("AB={sAB} AC={sAC} AD={sAD} BC={sBC} BD={sBD} CD={sCD} [P={P} Q={Q} R={R} S={S} T={T} U={U} V={V}]")
```

Solution: The scores in the matches were: AvB = 1-0; AvC = 0-2; AvD = 8-6; BvC = 0-0; BvD = 0-0; CvD = 0-0.

However I think it is possible to argue that there could be a second possible solution.

The scores in the matches could be: AvB = 1-0; AvC = 1-2; AvD = 7-6; BvC = 0-0; BvD = 0-0; CvD = 0-0.

In this scenario the first table looks like:

```  pts w  l  d  f  a  gd
C: 4  1  0  2  2  1  +1
A: 4  2  1  0  9  8  +1
B: 2  0  1  2  0  1  -1
D: 2  0  1  2  6  7  -1```

Both C and A, and B and D have the same number of points, and the same goal difference, so without further information about how the order of tied teams is decided it is possible that the table would be presented in the order above.

The second table would look like:

```  pts w  l  d  f  a  gd
A: 6  2  1  0  9  8  +1
C: 5  1  0  2  2  1  +1
B: 2  0  1  2  0  1  -1
D: 2  0  1  2  6  7  -1```

A and C have swapped positions (as required), and V = 5 does not appear as a letter in the first table, so it is consistent with the problem statement.

This additional solution can be obtained by relaxing the definition of is_ordered() to:

```def is_ordered(pX, pY, dX, dY):
return pX > pY or (pX == pY and dX >= dY)
```