Brain-Teaser 943: Order in football
From The Sunday Times, 17th August 1980 [link]
There are three teams In the Midchester football league: Albion, United and Victoria. During the season they play each other twice; once at home and once away.
A team gets two points for a win and one point tor a draw. After each match the local paper publishes the current league table. In this table the teams are listed according to points and if two or more teams have equal points then they are listed according to goal difference, (i.e. “goals for” minus “goals against”). If two or more teams have equal points and equal goal difference then they are listed alphabetically.
At the end of last season the sports editor published the results of all the matches:
Albion 4 – United 0
Albion 0 – Victoria 0
United 0 – Albion 1
United 2 – Victoria 0
Victoria 3 – Albion 0
Victoria 1 – United 2He also said that each of the six league tables published during the season had put the teams in a different order. Thus each of the six possible orders of the teams (AUV, AVU, UAV, UVA, VAU, VUA) had occurred in one of the six league tables. Finally, he said that the third match of the season had been the draw, A vs. V.
List the six matches in the order in which they were played during the season.
This puzzle is included in the book The Sunday Times Book of Brainteasers (1994).
[teaser943]

Jim Randell 8:09 am on 1 July 2026 Permalink |
I thought about writing a recursive solver that checks the orders of the teams are all different as each match is chosen, but it is more straightforward to just generate the possible orderings of the matches, calculate the orders of the teams after each match, and see if they are all different.
This Python program runs in 74ms. (Internal runtime is 1.9ms).
from enigma import (compare, subsets, join, seq_all_different, printf) teams = "AUV" # labels for the teams points = [0, 1, 2] # point for l, d, w # produce the orders for the teams after each of the matches is played def orders(ms): # go through the matches, and accumulate points, goal difference for each team (pts, gd, tss) = (dict.fromkeys(teams, 0), dict.fromkeys(teams, 0), list()) for ((X, gX), (Y, gY)) in ms: # assign points pts[X] += compare(gX, gY, vs=points) pts[Y] += compare(gY, gX, vs=points) # count goals gd[X] += (gX - gY) gd[Y] += (gY - gX) # calculate order ts = join(sorted(teams, key=(lambda k: (pts[k], gd[k], -ord(k))), reverse=1)) tss.append(ts) return tss # the matches, and the outcomes: # this match was 3rd match3 = (("A", 0), ("V", 0)) # and these are the remaining matches matches = [ (("A", 4), ("U", 0)), (("U", 0), ("A", 1)), (("U", 2), ("V", 0)), (("V", 3), ("A", 0)), (("V", 1), ("U", 2)), ] # choose an order for the remaining matches for ms in subsets(matches, size=len, select='P', fn=list): # insert match3 into the 3rd position (= index 2) ms.insert(2, match3) # calculate the team orders after each match tss = orders(ms) # check they are all different if seq_all_different(tss): for (i, (((X, x), (Y, y)), ts)) in enumerate(zip(ms, tss), start=1): printf("{i}: {X} vs. {Y} ({x} - {y}); order = {ts}") printf()Solution: The order of the matches was: U vs. V; V vs. A; A vs. V; U vs. A; A vs. U; V vs. U.
Giving the following orderings of the teams after each match:
LikeLike
Ruud 8:18 pm on 1 July 2026 Permalink |
Correction:
import peek import itertools for matches in itertools.permutations("AU40 AV00 UA01 UV20 VA30 VU12".split()): if matches[2] != "AV00": continue points = dict.fromkeys("AUV", 0) goals_difference = dict.fromkeys("AUV", 0) score = {"A": (0, 0, "A"), "U": (0, 0, "U"), "V": (0, 0, "V")} seen = set() for match in matches: team0, team1 = match[:2] goals0, goals1 = map(int, match[2:]) points[team0] += (goals0 > goals1) + (goals0 >= goals1) points[team1] += (goals1 > goals0) + (goals1 >= goals0) goals_difference[team0] += goals0 - goals1 goals_difference[team1] += goals1 - goals0 score[team0] = (points[team0], goals_difference[team0], team0) score[team1] = (points[team1], goals_difference[team1], team1) order = tuple(x[2] for x in sorted(score.values(), key=lambda x: (-x[0], -x[1], ord(x[2])))) if order in seen: break seen.add(order) else: peek(matches)LikeLike