# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1203: The away goals rule

From New Scientist #2359, 7th September 2002 [link]

Albion played 18 fixtures in a league in which the result of each fixture was decided by the aggregate scores achieved by the teams over two legs, home and away.  But the rule that “away goals count double” applied in all circumstances;  so a team could win a fixture even though it had scored fewer actual goals than the opposition: a team that drew at home 1-1 and lost away 4-6 would win 9-8 on aggregate after the away goals rule was applied.

In each fixture, Albion scored fewer actual goals over the two legs than the opposition but won on aggregate once the away goals rule was applied.  Even with away goals counting double Albion’s aggregate score in each fixture always remained in single figures. Twelve different scores were involved in Albion’s home legs, six occurring once  and six twice. The scores in the 18 away legs were all different.  (A win by any score is different from a loss by that score).

What were the scores in the away legs of the fixtures in which Albion drew at home 0-0? Give each answer in the form xy, with Albion’s score first in each case and without applying the away goals rule.

[enigma1203]

### One response to “Enigma 1203: The away goals rule”

1. Jim Randell 12 September 2015 at 7:51 am

This Python program runs in 86ms.

```from collections import defaultdict, Counter
from itertools import combinations, product
from enigma import irange, printf

# a fixture is two games, a home game, score (a, b), and an away game, score (c, d)
# away goals count double so the aggregate score is: (a + 2c, 2b + d)

# find pairs (x, y) such that (x + 2y) is a single figure
xys = list()
for x in irange(0, 9):
for y in irange(0, (9 - x) // 2):
xys.append((x, y, x + 2 * y))

# find scores (a, b), (c, d), where the aggregate scores a + 2c (x) and 2b + d (y) are single digits
# accumulate possible (a, b, c, d) scores as: (c, d) -> [(a, b, c, d), ...]
scores = defaultdict(list)
for ((a, c, x), (d, b, y)) in product(xys, repeat=2):
# A's actual goals (a + c) were less than the opposition (b + d)
# but A win's on aggregate, so x > y
if a + c < b + d and x > y:
printf("home: {a}-{b}, away: {c}-{d} -> aggregate: {x}-{y}")
scores[(c, d)].append((a, b, c, d))

# choose 18 of the (c, d) scores
for cds in combinations(scores, 18):
# and generate possible fixtures for these
for ss in product(*(scores[cd] for cd in cds)):
# count the occurrences of (a, b)
c = Counter((a, b) for (a, b, c, d) in ss)
# and then count those occurrences, and look for 6 that occur once and 6 the occur twice
if sorted(Counter(c.values()).items()) == [(1, 6), (2, 6)]:
# output the list of fixtures
printf("fixtures = {ss}")
# and the solution (away legs for home legs of 0-0)
printf("home = (0, 0): away = {x}", x=list((c, d) for (a, b, c, d) in ss if (a, b) == (0, 0)))
```

Solution: The scores in the away legs of the fixtures where Albion drew 0-0 at home were 4-7 and 2-3.

The scores in the home and away legs of each fixture as well as the aggregate score for Albion are given in the diagram below:

In fact there are only 18 possible scores for the away legs, so we need to choose a corresponding home leg score for each possible away leg score, and there is only one way to do this such that six of the home leg scores are used once and six of them are used twice. In the diagram the 18 fixtures are grouped by home leg score so it is easy to see how many times each home leg score is used.