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 2
He 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 10:20 am on 28 July 2026 Permalink |
Starting with a triangle with sides a, b, c. Then the circular pond is concentric with the incircle of the triangle, so we are interested in the distances from the incentre (= I) to the vertices of the triangle (= u, v, w).
The semi-perimeter (= s) of the triangle is given by:
And the lengths of the sides of the triangle can be written:
And so the distances we are interested in are given by:
We can calculate area (= A) of the triangle using Heron’s formula:
And the inradius (= r) can then be calculated:
The following Python program considers possible sides of the triangle (a, b, c), and looks for scenarios where 2 of the distances from the incentre to the vertices are whole numbers.
It runs in 76ms. (Internal runtime is 665µs).
from enigma import (Rational, decompose, sq, is_square, sqrt, seq2str, printf) Q = Rational() # semi-perimeter s = 27 # consider possible sides of the triangle (a, b, c); a + b + c = 2s for (a, b, c) in decompose(2 * s, 3, increasing=1, sep=0): # if the area of the triangle is A, use Heron's formula to calculate A^2 A2 = s * (s - a) * (s - b) * (s - c) # check for valid triangles if not (A2 > 0): continue # inradius = r, r = A/s, calculate r^2 r2 = Q(A2, sq(s)) # calculate the squares of the distances from the incentre to the vertices d2s = tuple(r2 + sq(s - v) for v in (a, b, c)) # and look for situations where exactly 2 of these are perfect squares k = sum(1 for d2 in d2s if is_square(d2)) if k != 2: continue # output solution ds = tuple(sqrt(d2) for d2 in d2s) printf("a={a} b={b} c={c} -> A2={A2} r2={r2} -> d2s={d2s} ds={ds}", d2s=seq2str(d2s), ds=seq2str(ds))Solution: The shortest side of the lawn is 6 m.
And the other two sides are 24 m each. (So the triangle is isosceles).
Giving distances from the incentre to the vertices of 4 m, 4 m, 21.166 m (= 8√7).
LikeLike
Jim Randell 11:48 am on 2 August 2026 Permalink |
If at least one of the (r² + (s − v)²) is a square number (to give a whole number root), then it follows that r² must be an integer, and so each of u², v², w² is also a whole numbers.
And we can simplify the calculations of u², v², w² to be just in terms of a, b, c:
The program can then be simplified slightly to:
from enigma import (decompose, div, tuples, is_square, sqrt, seq2str, printf) # semi-perimeter s = 27 # consider possible sides of the triangle (a, b, c); a + b + c = 2s for (a, b, c) in decompose(2 * s, 3, increasing=1, sep=0): # check for valid triangles if not (a + b > c): continue # calculate the squares of the distances from the incentre to the vertices d2s = tuple(div((s - i) * j * k, s) for (i, j, k) in tuples((a, b, c), 3, circular=1)) if None in d2s: continue # look for situations where exactly 2 of these are perfect squares k = sum(1 for d2 in d2s if is_square(d2)) if k != 2: continue # output solution ds = tuple(sqrt(d2) for d2 in d2s) printf("a={a} b={b} c={c} -> d2s={d2s} ds={ds}", d2s=seq2str(d2s), ds=seq2str(ds))LikeLike
Frits 1:54 pm on 28 July 2026 Permalink |
Doing most of the checks in decompose().
from math import prod # decompose number <t> into <k> non-decreasing numbers and semi-perimeter logic def decompose(t, k, m=0, sp=0, s=[]): if k == 1: if not s or t >= s[-1]: s.append(t) # r^2 = (sp - a) * (sp - b) * (sp - c) / sp must be a positive integer p = prod(sp - x for x in s) if p > 0 and p % sp == 0: yield s, p // sp else: for n in range(m, (t // k) + 1): yield from decompose(t - n, k - 1, n, sp, s + [n]) # semi-perimeter s = 27 # consider possible sides of the triangle (a, b, c); a + b + c = 2s for (a, b, c), r2 in decompose(2 * s, 3, 1, s): # calculate the squares of the distances from the incentre to the vertices d2s = [r2 + (s - v)**2 for v in (a, b, c)] # and look for situations where exactly 2 of these are perfect squares if sum(round(rt := d2**.5) == rt for d2 in d2s) != 2: continue print("answer:", min(a, b, c))LikeLike