The phone numbers that ring three times the intended number must occur within the range 4 to 33.

As there are only 3 numbers ending in each digit in this range, at least 4 digits, y, must be wired to 3y mod 10. These digits must be four of 1,2,3,4,6,7,8,9, as 0 and 5 are not wired to themselves.

This test provides a significant performance improvement.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from itertools import permutations as perm rewired=[0]*10 for p in perm(range(1,10)): rewired[0]=p[0] for n in xrange(8): rewired[p[n]]=p[n+1] rewired[p[8]]=0 if sum(1 for n in (1,2,3,4,6,7,8,9) if rewired[n]==(3*n)%10)>=4: if len([n for n in xrange(4,34) if 10*rewired[n//10]+rewired[n%10] == 3*n])>10: if len([n for n in xrange(5,50) if 10*rewired[n//10]+rewired[n%10] == 2*n])==4: print "0 to 9 are wired to", rewired,"respectively" |

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from itertools import permutations as perm rewired=[0]*10 for p in perm(range(1,10)): rewired[0]=p[0] for n in xrange(8): rewired[p[n]]=p[n+1] rewired[p[8]]=0 if len([n for n in xrange(34) if 10*rewired[n//10]+rewired[n%10] == 3*n])>10: if len([n for n in xrange(50) if 10*rewired[n//10]+rewired[n%10] == 2*n])==4: print "0 to 9 are wired to", rewired,"respectively" |

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from itertools import permutations # test if the permutation p is cyclic def full_cycle(p): n = nn = 0 cnt = len(p) while True: cnt -= 1 nn = p[nn] if nn == n: return not cnt # If all hunndred office numbers are in cycles of length ten # then the keypad digits must also form a cycle of length ten # rearrange the phone's digits for p in permutations(range(10)): # discard any permutations with short cycles if not full_cycle(p): continue # map the numbers input to the numbers called d = {n:10 * p[n // 10] + p[n % 10] for n in range(100)} # now check that at least four numbers are doubled if sum(1 if d[n] == 2 * n else 0 for n in range(100)) < 4: continue # and that more than ten are tripled if sum(1 if d[n] == 3 * n else 0 for n in range(100)) <= 10: continue print(''.join('{:02d} rings {:02d}, '.format(n, d[n]) for n in (1, 23, 45, 67, 89))[:-2]) |