Teaser 2510: [Extension number]
From The Sunday Times, 31st October 2010 [link] [link]
Since we last met them, George has moved departments yet again and Martha has forgotten the extension number.
“No problem”, said the operator.
“If you write down the number itself, the average of its four digits, the sum of its four digits, and the cube root of the difference between the number and its reverse (which is smaller), then you will write no digit more than once”.
What is George’s new extension number?
This puzzle was originally published with no title.
[teaser2510]
Jim Randell 10:37 am on 7 October 2025 Permalink |
Although not explicitly stated, I assumed both the average (mean) of the digits and the cube root are integers.
You get the same answer to the puzzle if you do consider fractional averages, written either in fraction form (1/4, 1/2, 3/4) or in decimal (.25, .5, .75).
The following Python program runs in 65ms. (Internal runtime is 1.9ms).
from enigma import (irange, subsets, multiset, nsplit, nconcat, is_cube, rev, join, printf) # choose 4 (distinct) digits for the phone number for ds in subsets(irange(0, 9), size=4): # accumulate written digits m = multiset.from_seq(ds) # sum of the digits in the number t = sum(ds) m.update_from_seq(nsplit(t)) if m.is_duplicate(): continue # average (= mean) of the digits in the number (a, f) = divmod(t, 4) if f > 0: continue m.add(a) if m.is_duplicate(): continue # choose an ordering for the digits in the number for ns in subsets(ds, size=len, select='P'): if ns[-1] > ns[0]: continue # first digit > last digit n = nconcat(ns) r = nconcat(rev(ns)) # is the difference a positive cube? c = is_cube(n - r) if not c: continue if m.combine(nsplit(c)).is_duplicate(): continue # output solution printf("number={ns} [sum={t} avg={a} cbrt={c}]", ns=join(ns))Solution: The number is: 8147.
The sum of the digits is: 20.
The average (mean) of the digits is: 5.
And the difference between the number and its reverse is: 8147 − 7418 = 729 = 9³.
So we would write the digits: “8147; 20; 5; 9”.
LikeLike
Jim Randell 5:04 pm on 7 October 2025 Permalink |
Or even faster with some analysis:
If the phone number is abcd (where a > d, then we have:
So n^3 is a multiple of 9, and so n is a multiple of 3.
This Python program has an internal runtime of 277µs.
from enigma import (irange, cb, group, unpack, subsets, div, nsplit, printf) # possible cubes cubes = dict((cb(n), nsplit(n)) for n in irange(3, 21, step=3)) # map 90 * (b - c) values to possible (b, c) pairs fn = unpack(lambda b, c: 90 * (b - c)) g = group(subsets(irange(0, 9), size=2, select='P'), by=fn) # choose (a, d) values (a > d) for (d, a) in subsets(irange(0, 9), size=2): x = 999 * (a - d) # consider possible cubes for (n3, n) in cubes.items(): # find (a, b) values for (b, c) in g.get(n3 - x, ()): ds = [a, b, c, d] ds.extend(n) if len(set(ds)) != len(ds): continue t = a + b + c + d m = div(t, 4) if m is None: continue ds.append(m) ds.extend(nsplit(t)) if len(set(ds)) != len(ds): continue # output solution printf("{a}{b}{c}{d} [cube={n3} total={t} avg={m}]")LikeLike
Ruud 4:30 pm on 7 October 2025 Permalink |
import istr cube_root = {istr(i**3): istr(i) for i in range(22)} for i in istr.range(1000, 10000): if sum(i).is_divisible_by(4) and (diff := i - i[::-1]) in cube_root.keys() and (i | sum(i) / 4 | sum(i) | cube_root.get(diff, "**")).all_distinct(): print(i)LikeLike
Frits 7:17 am on 8 October 2025 Permalink |
# n^3 = 1000(a - d) + 100(b - c) + 10(c - b) + (d - a) # n^3 = 999(a - d) + 90(b - c) # n^3 = 3^3.(37.(a - d) + 10.(b - c)/3) cubes = [i**3 for i in range(10)] # dictionary of cubes per cube unit digit dct = {cubes[i] % 10: cubes[i] for i in range(10)} for a_d in range(1, 10): # 37.a_d + delta should be a cube (delta in {-30, -20, -10, 10, 20, 30}) m37 = a_d * 37 delta = dct[m37 % 10] - m37 if delta not in [-30, -20, -10, 10, 20, 30]: continue b_c = 3 * delta // 10 # a + b + c + d = 4.avg or 2.d + 2.c + (a - d) + (b - c) = 4.avg if (a_d + b_c) % 2: continue cuberoot2 = round((m37 + delta)**(1/3)) cuberoot = 3 * cuberoot2 ns = set(int(x) for x in str(cuberoot)) for a in range(a_d, 10): d = a - a_d if len(ns_ := ns | {a, d}) != 3 + (cuberoot > 9): continue for b in range(b_c if b_c > 0 else 0, 10 if b_c > 0 else 10 + b_c): c = b - b_c if not ns_.isdisjoint({b, c}): continue avg, r = divmod(sm := a + b + c + d, 4) if r: continue nums = ns_ | {b, c, avg} | set(int(x) for x in str(sm)) if len(nums) != 6 + len(ns) + (sm > 9): continue print("answer:", 1000 * a + 100 * b + 10 * c + d)LikeLike