Teaser 2412: [Triangular lawn]
From The Sunday Times, 14th December 2008 [link]
I have a triangular lawn with sides a whole number of metres in length. Its perimeter is 54 metres. A circular water feature is equidistant from each of the three sides. I have measured the distance from the centre of the water feature to each of the corners of the lawn: in two cases, the distance is a whole number of metres.
What is the length of the shortest side of the lawn?
This puzzle was originally published with no title.
[teaser2412]
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