Teaser 3128: Tetrahedral towers
From The Sunday Times, 4th September 2022 [link] [link]
I have a large number (but fewer than 2000) of identical spherical bonbons, arranged exactly as a tetrahedral tower, having the same number of bonbons along each of the six edges of the tower, with each bonbon above the triangular base resting on just three bonbons in the tier immediately below.
I apportion all my bonbons between all my grandchildren, who have different ages in years, not less than 5, so that each grandchild can exactly arrange his or her share as a smaller tetrahedral tower, having the same number of tiers as his or her age in years.
The number of my grandchildren is the largest possible in these circumstances.
How many tiers were in my original tower? And how old in years are the eldest and youngest of my grandchildren?
[teaser3128]














Jim Randell 4:46 pm on 2 September 2022 Permalink |
This Python program constructs the tetrahedral numbers we are interested in, and then looks for subsets that also sum to a tetrahedral number.
It runs in 178ms.
Run: [ @replit ]
from enigma import (irange, inf, tri, reverse, subsets, Accumulator, printf) # compute tetrahedral numbers, n >=5, tetra[n] < 2000 tetra = dict() t = 0 for n in irange(1, inf): t += tri(n) if not (t < 2000): break if n < 5: continue tetra[n] = t rev = reverse(tetra) # consider possible ages of grandchildren r = Accumulator(fn=max, collect=1) for ns in subsets(sorted(tetra.keys()), min_size=2): t = sum(tetra[n] for n in ns) n = rev.get(t) if n: r.accumulate_data(len(ns), (ns, n)) # output solution printf("{r.value} grandchildren") for (ns, n) in r.data: printf("-> ages = {ns}; tetra[{n}] = {t}", t=tetra[n])Solution: The original tower had 19 tiers. The eldest grandchild is 12 years old. The youngest grandchild is 5 years old.
In total there are tetra[19] = 1330 bonbons.
There are 8 grandchildren. Their ages are: 5, 6, 7, 8, 9, 10, 11, 12.
And:
There are possible sets of grandchildren ages of size: 2, 3, 4, 5, 6, 7, 8:
The largest number of grandchildren (8) has only one corresponding set, and this gives the answer to the puzzle.
LikeLike
Jim Randell 10:33 pm on 2 September 2022 Permalink |
Or a bit longer, but faster.
This Python program runs in 56ms. (Internal run time is 1.7ms).
Run: [ @replit ]
from enigma import (irange, inf, tri, reverse, append, Accumulator, printf) # compute tetrahedral numbers, n >=5, tetra[n] < 2000 tetra = dict() t = mx = 0 for n in irange(1, inf): t += tri(n) if not (t < 2000): break if n < 5: continue tetra[n] = t mx = t rev = reverse(tetra) # make sums of tetras sums = {(): 0} for k in sorted(tetra.keys()): v = tetra[k] xs = dict((append(ns, k), t + v) for (ns, t) in sums.items() if not (t + v > mx)) sums.update(xs) # look for sums that are themselves tetras r = Accumulator(fn=max, collect=1) for (ns, t) in sums.items(): n = rev.get(t) if n: r.accumulate_data(len(ns), (ns, n)) # output solution printf("{r.value} grandchildren") for (ns, n) in r.data: printf("-> ages = {ns}; tetra[{n}] = {t}", t=tetra[n])LikeLike
Robert Brown 5:21 pm on 2 September 2022 Permalink |
I found this:
How many tiers were in my original tower, and how old in years are the eldest and youngest of my grandchildren?
LikeLike
Jim Randell 5:30 pm on 2 September 2022 Permalink |
@Robert: Thanks. I think I’ve got the complete puzzle now.
LikeLike
GeoffR 10:33 pm on 2 September 2022 Permalink |
# Full tetrahedral list below 2000, starting at 5th number # Ref: http://oeis.org/A000292 - assume youngest age = 5 # List starting from 5th tetrahedral number Tet_Nums = [35, 56, 84, 120, 165, 220, 286, 364, 455, 560, 680, 816, 969, 1140, 1330, 1540, 1771] # Dictionary to reference tetrahedral numbers and ages ages = range(5, 22) TN = dict(zip(Tet_Nums, ages)) # Iterate from both ends of tetrahedral numbers list # Largest possible number needed from end of list for a in reversed(Tet_Nums): nsum = 0 L =[] # list of grandchildren's tetrahedral numbers for b in (Tet_Nums): nsum += b L.append(b) if nsum > a: continue if nsum == a: print('Tiers in original tower = ', TN[nsum], "no.") for x in L: print('Grandchild\'s Age =', TN[x], "years") exit() # single solution only neededLikeLike
Jim Randell 3:15 pm on 4 September 2022 Permalink |
@GeoffR: It looks like this code looks for sets of consecutive ages starting from 5. Which is somewhat more specific than the puzzle text requires.
LikeLike
GeoffR 5:03 pm on 4 September 2022 Permalink |
@Jim: Yes, you are correct..
LikeLike