Teaser 2468: [Entry codes]
From The Sunday Times, 10th January 2010 [link]
The entry code to George and Martha’s block of flats is a four-digit number consisting of four different non-zero digits. Following a breach of security, management has changed the code. “I can see what they have done”, Martha says after some protracted calculations. “They have taken a multiple of the old code to give a five-digit number, added up those five digits, then squared this total to give the new code”. “Being of simple mind”, replies George, “I’d have said that they’ve simply reversed the old code”.
What was the old code?
This puzzle was originally published with no title.
[teaser2468]
Jim Randell 7:45 am on 19 August 2025 Permalink |
From George’s assessment we can see that the new code consists of 4 different non-zero digits.
From Martha’s assessment we can see that the new code must be a square number.
So we can look at 4-digit squares, consisting of 4 different non-zero digits, for the new number, reverse it, to get the old number, and then see if we can apply Martha’s algorithm to the old number to get the new number.
This Python program runs in 69ms. (Internal runtime is 658µs).
from enigma import (irange, sq, nsplit, nrev, dsum, printf) # Martha's algorithm def martha(n): # consider 5-digit multiples of n for m in irange.round(10000, 99999, step=n, rnd='I'): # find the square of the digit sum yield sq(dsum(m)) # the new code is a 4-digit square with no repeated digits for i in irange(36, 99): new = sq(i) ds = nsplit(new) if 0 in ds or len(set(ds)) != len(ds): continue # the old code is the reverse of the new old = nrev(new) # can we apply Martha's algorithm? if new in martha(old): # output solution printf("new = {new}; old = {old}")Solution: The old code was: 6921.
We can apply Martha’s technique to this number as follows:
or:
LikeLike
Jim Randell 7:20 am on 21 August 2025 Permalink |
Using the [[
SubstitutedExpression]] solver from the enigma.py library:LikeLike
Frits 12:13 pm on 19 August 2025 Permalink |
# find a multiple of <n> that has 5 digits and a digit sum of <t> def multiple(n, t): # makes sure of a 5-digit multiple with first digit high enough m = 9999 if t - 37 <= 0 else (t - 36) * 11111 - 1 # reverse looping in order to find a solution sooner for k in range(99999 // n, m // n, -1): if sum(int(x) for x in str(k * n)) == t: return True return False # suitable old codes and squares sqs = [(int(i2[::-1]), i) for i in range(32, 46) if '0' not in (i2 := str(i * i)) and len(set(i2)) == 4] for n, t in sqs: if multiple(n, t): print("answer:", n)LikeLike
GeoffR 2:42 pm on 20 August 2025 Permalink |
from itertools import permutations from enigma import nsplit digits = set('123456789') from math import isqrt def is_sq(x): return isqrt(x) ** 2 == x for n in permutations (digits, 4): a, b, c, d = n abcd = int(a + b + c + d) for m in range(2, 80): # UB = 98765/1234 = 80 dig5 = m * abcd if dig5 < 10000:continue if dig5 > 99999:continue # find digits of 5 digit number d1, d2, d3, d4, d5 = nsplit(dig5) if 0 in (d1, d2, d3, d4, d5):continue # find new code new_code = (d1 + d2 + d3 + d4 + d5) ** 2 # new code is reverse of old code if str(new_code) == str(abcd) [::-1]: print(f"Old code was {abcd}.") # Old code was 6921.LikeLike
Ruud 7:03 am on 21 August 2025 Permalink |
import istr istr.int_format("04") for old in istr.concat(istr.permutations(istr.digits("1-9"), 4)): for n in range(2,10000): if len(old_n:=old * n) == 5: if sum(old_n) ** 2 == old[::-1]: print(old, n) else: if len(old_n) > 5: breakLikeLike
Ruud 7:20 am on 21 August 2025 Permalink |
As a one liner: import istr print( { old for old in istr.concat(istr.permutations(istr.digits("1-9"), 4)) for old_n in istr.range(int(2 * old), 100000, old) if len(old_n) == 5 and sum(old_n) ** 2 == old[::-1] } )LikeLike
GeoffR 10:37 am on 21 August 2025 Permalink |
LikeLike