Teaser 3337: Hidden PINs
From The Sunday Times, 6th September 2026 [link] [link]
Richard has opened a bank account. The bank has issued him with a telephone PIN and a debit card PIN; both PINs consist of four digits. The telephone PIN is a perfect square; its square root can be obtained from the card PIN if the first two digits are deleted from the card PIN. The card PIN is composed of four different digits in decreasing order; none of these digits occur in the telephone PIN.
If I told you whether the telephone PIN has any repeated digits (or not), you would be able to find both PINs.
What is the debit card PIN?
[teaser3337]





Jim Randell 6:12 am on 6 September 2026 Permalink |
This Python program uses the [[
SubstitutedExpression]] solver from the enigma.py library to generate possible candidate PINs directly from the conditions given in the puzzle text. And then uses the [[filter_unique()]] function to determine which of the candidates provides the answer to the puzzle.It runs in 69ms. (Internal runtime is 3.8ms)
from enigma import (SubstitutedExpression, filter_unique, fcompose, item, is_duplicate, printf) # generate candidate PINs def generate(): # construct a solver to find the PINs; tel PIN = ABCD; card PIN = EFGH exprs = [ # tel PIN is a perfect square (= (GH)^2) "sq(GH) = ABCD", # card PINs digits are in decreasing order "E > F", "F > G", "G > H", ] # none of the card PINs digits appear in the tel PIN distinct = ["AEFGH", "BEFGH", "CEFGH", "DEFGH"] p = SubstitutedExpression(exprs, d2i=dict(), distinct=distinct, answer="(ABCD, EFGH)") # output and return candidates for (t, c) in p.answers(verbose=""): printf("[tel = {t:04d}, card = {c:04d}]") yield (t, c) # if we knew whether the tel PIN had repeated digits, we could work out both PINs frep = fcompose(item(0), is_duplicate) for (t, c) in filter_unique(generate(), frep).unique: printf("(repeat = {f}) -> tel = {t:04d}, card = {c:04d}", f=frep((t, c)))Solution: [To Be Revealed]
LikeLike
Ruud van der Ham 7:42 am on 6 September 2026 Permalink |
import peek import istr for tel_pin in istr.squares(length=4): for card_pin01 in istr.range(length=2): card_pin = card_pin01 | tel_pin.sqrt() if card_pin.all_distinct() and card_pin.is_decreasing() and len(set(tel_pin) & set(card_pin)) == 0 and not tel_pin.all_distinct(): peek(tel_pin, card_pin)LikeLike
Ruud van der Ham 12:20 pm on 6 September 2026 Permalink |
I misread the last clause and thought it said that the telephone pin HAS any repeated digits.
This is an updated version:
import istr collect_telephone_pin_has_repeating = {False: [], True: []} for telephone_pin in istr.squares(length=4): for card_pin01 in istr.range(length=2): card_pin = card_pin01 | telephone_pin.sqrt() if card_pin.all_distinct() and card_pin.is_decreasing() and len(set(telephone_pin) & set(card_pin)) == 0: collect_telephone_pin_has_repeating[not telephone_pin.all_distinct()].append((telephone_pin, card_pin)) for has_repeating, solutions in collect_telephone_pin_has_repeating.items(): if len(solutions) == 1: print("telephone pin=", solutions[0][0], "card pin=", solutions[0][1])LikeLike