From The Sunday Times, 1st October 1978 [link]

Margaret was demonstrating the use of a pocket calculator to her grandfather. (Keyboard shown above). It was of the type having algebraic logic, which does continuous mixed calculations (e.g. 5 + 2 × 3 = 21). She also demonstrated that keying two consecutive operations results in the second taking preference (e.g. 5 +× 2 = 10).
Margaret asked grandfather to calculate 80 × 5 + 40 − 10; but unfortunately grandfather’s hands were a little shaky and he was prone to strike keys horizontally oг vertically adjacent to the correct one.
Having entered the sum grandfather was about to press the = key (fortunately he hadn’t pressed it before) when Margaret stopped him.
“You have made just two errors so far, and they were consecutive”, she said, “but don’t worry, if you divide by your age on your next birthday, then press the = key, you will get the correct answer to the calculation”.
Grandfather completed the calculation and correctly pressed the = key.
“Wrong again”, said Margaret, “interesting answer though — if you deduct grandmother’s age, and take the cube root of the remainder, you will get the sum of your age, and mine, on our last birthdays”.
How old are Margaret, grandmother and grandfather?
Another early calculator-based puzzle.
This puzzle is included in the book The Sunday Times Book of Brain-Teasers: Book 2 (1981). The puzzle text above is taken from the book.
[teaser895]
Jim Randell 9:50 am on 1 October 2026 Permalink |
If you follow the instructions (and don’t make any mistakes), you can fill out the grid fairly easily.
Here is a simple Python program the fills out the grid as specified, backtracking when an impossible situation occurs. We are only interested in the first solution, so [[
solve()]] operates on the grid in-place.It runs in 75ms. (Internal runtime is 4.6ms).
from enigma import (irange, subsets, join, printf) digits = list(irange(1, 9)) # additional cells to be checked for a box box = list([[], [], []] for _ in irange(3)) cells = subsets([0, 1, 2], size=2, select='M') for ((r1, c1), (r2, c2)) in subsets(cells, size=2): if r1 != r2 and c1 != c2: box[r2][c2].append((r1 - r2, c1 - c2)) # fill out the first possible digit in each box def solve(g, i=0): # are we done? if i == 81: yield g else: (r, c) = divmod(i, 9) for d in digits: # check col, row, box if any(d == g[x][c] for x in irange(r)): continue if any(d == g[r][y] for y in irange(c)): continue if any(d == g[r + x][c + y] for (x, y) in box[r % 3][c % 3]): continue g[r][c] = d yield from solve(g, i + 1) g[r][c] = 0 # find the first solution, starting with an empty grid g0 = list([0] * 9 for _ in irange(9)) for g in solve(g0): # output solution printf("{g}", g=join(g, sep="\n")) break # only want the first solutionSolution: The last 3 digits on the bottom row are: 6, 4, 2.
The complete grid is:
LikeLike
Frits 4:14 pm on 1 October 2026 Permalink |
Using a 1-dimensional grid and precomputing “neighbours”.
# dimensions NxN N0 = 3 # boxsize N = N0 * N0 N2 = N * N dgts = range(1, N + 1) row = lambda i: i // N col = lambda i: i % N # return box number box = lambda i: (i // (N * N0)) * N0 + (i % (N)) // N0 neighbours = [] # for each cell precompute it's neighbours (in same row, column or box)) for i in range(N2): r, c, b = row(i), col(i), box(i) neighbours.append([j for j in range(N2) if j != i and (row(j) == r or col(j) == c or box(j) == b)]) # recursively solve the sudoku def solve(g, i=0): if i == N2: # done yield g else: # try to fill cell with numbers not yet used by it's neighbours used = {g[x] for x in neighbours[i]} for n in [j for j in dgts if j not in used]: g[i] = n yield from solve(g, i + 1) g[i] = 0 # backtrack g = [0] * N2 for s in solve(g): #for k in range(N): print(g[k * N:k * N + N]) print("answer:", g[N2 - 3:]) break # we only need the first solutionLikeLike