Teaser 2456: [Digit groups]
From The Sunday Times, 18th October 2009 [link]
A teacher asked each of her pupils to write the digits 1 to 9 in a row and then use dashes to divide their row of digits into groups, such as in 123-4-56-789. She then asked them to add up the numbers in each group and multiply all the totals together — so the above example would give the
answer 6×4×11×24 = 6336.Billy’s answer was an odd perfect square. Jilly’s answer was also a perfect square, but in her case each group of digits had more than one digit in it.
What were Billy’s and Jilly’s rows of digits and dashes?
This puzzle was originally published with no title, and no setter was given.
[teaser2456]
Jim Randell 8:14 am on 20 February 2026 Permalink |
This Python program runs in 69ms. (Internal runtime is 1.6ms)
from enigma import (irange, decompose, tuples, csum, multiply, is_square_p, printf) # the sequence of digits digits = list(irange(1, 9)) n = len(digits) # divide the digits into k groups (min groups = 1, max groups = n) for k in irange(1, n): for js in decompose(len(digits), k, increasing=0, sep=0, min_v=1): # split the digits into the groups gs = list(digits[i:j] for (i, j) in tuples(csum(js, empty=1), 2)) # calculate the result of the process r = multiply(sum(ns) for ns in gs) # both B and J found a square number if is_square_p(r): # B's was odd if r % 2 == 1: printf("Billy: {gs} -> {r}") # J's groups each have more than one digit if all(len(ns) > 1 for ns in gs): printf("Jilly: {gs} -> {r}")Solution: Billy = 12-3-456-78-9; Jilly = 12-3456-789.
So:
Here is a complete list of square numbers that can be formed this way:
LikeLike
ruudvanderham 12:07 pm on 20 February 2026 Permalink |
I make expressions by putting either )*( or + between the digits 1 – 8, like
(1)*(2+3+4+5)*(6+7)*(8)*(9)
and then evaluate that with eval.
For Jilly, I then also check whether the lengths of all parts split by ‘)*(‘ is greater than 2.
import itertools import math for ops in itertools.product(("+", ")*("), repeat=8): exp = "(1" + "".join(f"{op}{i}" for i, op in enumerate(ops, 2)) + ")" if math.isqrt(val := eval(exp)) ** 2 == val: if val % 2: print("Billy", exp, "=", val) else: if all(len(part) > 2 for part in exp.split(")*(")): print("Jilly", exp, "=", val)LikeLike
Ruud 3:41 pm on 20 February 2026 Permalink |
With a more elegant check for no groups of one digit:
import itertools import math for ops in itertools.product(("+", ")*("), repeat=8): exp = "(1" + "".join(f"{op}{i}" for i, op in enumerate(ops, 2)) + ")" if math.isqrt(val := eval(exp)) ** 2 == val: if val % 2: print("Billy", exp, "=", val) else: if all("+" in part for part in exp.split("*")): print("Jilly", exp, "=", val)LikeLike