Teaser 2423: [PIN combinations]
From The Sunday Times, 1st March 2009 [link]
Joe could not remember his six-digit PIN, but he did remember that it used the digits 1 to 6 in some order. He tried the following four without success:
6 1 2 5 3 4 4 6 5 3 2 1 2 3 4 1 6 5 3 2 6 5 4 1Actually, more than one digit in each of these numbers was in the correct place. Had Joe known this, he would have needed to try only a few more numbers to find his PIN.
How many more numbers did Joe need to try?
This puzzle was originally published with no title.
[teaser2423]













Jim Randell 8:58 am on 17 July 2026 Permalink |
Presumably the puzzle is asking how many possible combinations remain after the initial 4 attempts.
This Python program runs in 64ms. (Internal runtime is 820µs).
from enigma import (subsets, printf) # candidates already tried tries = [ (6, 1, 2, 5, 3, 4), (4, 6, 5, 3, 2, 1), (2, 3, 4, 1, 6, 5), (3, 2, 6, 5, 4, 1), ] # start with all orderings ss = list(subsets((1, 2, 3, 4, 5, 6), size=6, select='P')) # count the number of correct positions def count(xs, ys): return sum(1 for (x, y) in zip(xs, ys) if x == y) # more than one of the digits in each candidate was in the correct position for ts in tries: ss = list(ns for ns in ss if 1 < count(ns, ts) < 6) # output solution printf("remaining candidates = {n}", n=len(ss)) printf("-> {ss}")Solution: There are 3 combinations remaining.
The remaining candidates are:
In each case, each of the initial 4 attempts was correct for exactly 2 digits.
LikeLike
Ruud 4:17 pm on 17 July 2026 Permalink |
import istr def matches(n0, n1): return sum(i0 == i1 for i0, i1 in zip(n0, n1)) tries = istr(["612534", "465321", "234165", "326541"]) for n0 in istr.permutations(range(1, 7), join=True): if all(2 <= matches(n0, n1) <= 5 for n1 in tries): print(n0)LikeLike
Frits 12:54 pm on 21 July 2026 Permalink |
from itertools import permutations # candidates already tried tries = [ (6, 1, 2, 5, 3, 4), (4, 6, 5, 3, 2, 1), (2, 3, 4, 1, 6, 5), (3, 2, 6, 5, 4, 1), ] # count the number of correct positions (return 2 if two or more are correct) def count(xs, ys): found = 0 for x, y in zip(xs, ys): if x == y: if found: return 2 found = 1 return found rng, sols = set(range(1, 7)), [] # select values for first four positions for p4 in permutations(rng, 4): sol, hit1 = tuple(), [] # check the four attempts for a in tries: # check if last 2 digits of attempt must be correct if count(p4, a[:4]) == 0: # last 2 numbers of attempt must be different from the permutation if set(a[4:]).isdisjoint(p4): sol = p4 + a[4:] break else: # no break for n56 in permutations(rng - set(p4)): sol = p4 + n56 if all(count(sol, a) > 1 and sol != a for a in tries): sols.append(sol) continue # last 2 values are known if sol: if all(count(sol, a) > 1 and sol != a for a in tries): sols.append(sol) print("answer:", len(sols))LikeLike