Sunday Times Teaser 3005 – Tubular Bales
by Stephen Hogg
Published Sunday April 26 2020 (link)
Ten equal-length, rigid tubes, each a different prime-valued external radius from 11mm to 43mm, were baled, broadside, by placing the 43mm and 11mm tube together and the third tube, not the largest remaining, touching both of these. Each subsequent tube touched the previous tube placed and the 43mm tube. A sub-millimetre gap between the final tube placed and the 11mm tube, made a near perfect fit.
The radius sum of the first three tubes placed against the 43mm tube was a multiple of one of the summed radii. Curiously, that statement remains true when each of “four”, “five”, “seven” and “eight” replaces “three”. For “two” and “six” tubes placed their radius sum was a multiple of an as yet unplaced tube’s radius.
What radius tube, in mm, was placed last?
-
Brian Gladman permalink123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172from math import cos, asin, tau# the first outer tube; the rest except for the largest; the largestpr = [x for x in range(11, 44, 2) if all (x % p for p in {2, 3, 5})]t1, *tr8, t0 = pr# given three tube radii, (a, b, c), return the angle subtended# at the centre of tube <a> between the centres of tubes <b> and <c>def ang(a, b, c):t = b * c / (a * (a + b + c) + b * c)return 2 * asin(t ** 0.5)# return the length of the third side of a triangle with sides# of length <a> and <b> and an included angle <chi>def third(a, b, chi):return (a * a + b * b - 2 * a * b * cos(chi)) ** 0.5# place a tube in a sequence of outer tubes with# tr = tubes yet to be placed, tp = tubes placeddef place(tr, tp):nr = len(tp)# have we placed all but one tube?if nr == 8:# return the sequence of the nine outer tube radiiyield tp + trelse:# try to place another tubefor i, tn in enumerate(tr):# form the new remaining and placed sequencestrn = tr[:i] + tr[i+1:]tpn = tp + [tn]# pick the sequence in which there is a divisor# of the sum of the tube radiitf = trn if nr in {1, 5} else tpn# sum the tube radii (including the current one)sp = sum(tpn)# check that the sum is a multiple of a radius# in the appropriate sequenceif any(sp % t == 0 for t in tf):# and if so, place it and continue to the nextyield from place(trn, tpn)# for saving the radii of the last tubes placedsol = set()# consider possible sequences of outer tube placmentsfor s in place(tr8, [t1]):# sum the angles subtended by the outer tubes# at the centre of the central tubeasum = sum(ang(t0, a, b) for a, b in zip(s, s[1:]))# find the distance between the first and last# outer tubes placed and hence the gapln = third(t0 + s[0], t0 + s[-1], tau - asum)gap = ln - (s[0] + s[-1])# save the radius of the last tube placed if the# gap is less than a millimetre and the third# placed tube is not the largest outer tubeif 0 <= gap < 1 and s[1] != tr8[-1]:sol.add(s[-1])print(f"{s} gap = {1000 * gap:>4.0f}\u03bcm")v, *r = solif not r:print(f"\nThe last tube placed has a radius of {v}mm.")