Teaser 2108: Touch of magic
From The Sunday Times, 9th February 2003 [link]
Place a single digit into each of the nine squares, such that:
- There is no repeat in any row and no repeat in any column.
- Each row, read in either direction, is a three-figure prime.
- Each column, read up or down, is a three-figure prime.
What is the sum of your nine digits?
[teaser2108]

Jim Randell 9:01 am on 1 June 2023 Permalink |
We can use the [[
SubstitutedExpression]] solver from the enigma.py library to solve this puzzle.The following run file executes in 79ms. (Internal runtime of the generated code is 11ms).
Run: [ @replit ]
Solution: The sum of the digits is 50.
One arrangement is:
We also get a solution if we reverse the rows (left to right), or reverse the order of the rows (top to bottom), or both.
LikeLike
Frits 5:19 pm on 2 June 2023 Permalink |
from itertools import permutations # 143 prime numbers between 100 and 1000 P = [3, 5, 7] P += [x for x in range(11, 33, 2) if all(x % p for p in P)] P = [str(x) for x in range(101, 1000, 2) if all(x % p for p in P)] # a list of all valid prime numbers p_both = [p for p in P if len(set(p)) == 3 and p[::-1] in P] # a list of all valid prime numbers without it's reverse p_single = [p for p in p_both if p[0] < p[2]] # 2 ends (also for middle layers) # / \ # +---+---+---+ # | | | | # +---+---+---+ # | | | | <-- edge # +---+---+---+ # | | | | # +---+---+---+ # \ | / # 1 side ends = set(y for x in p_single for y in (x[0], x[2])) edges = set(x[1] for x in p_single if x[1] in ends) middle_layers = [x[::k] for x in p_single if set([x[0], x[2]]) <= edges for k in (-1, 1)] # a side of 3 cells must have an odd edge and it's edge must be an end sides = [x[::k] for x in p_single if x[1] in "13579" and x[1] in ends for k in (-1, 1)] # pick 2 different sides for top and bottom horizontal layer for p in permutations(sides, 2): s1, s2 = p # vertically digits may not match if any(s1[i] == s2[i] for i in range(3)): continue # pick a horizontal middel layer for m in middle_layers: # check column for prime numbers if any(s1[i] + m[i] + s2[i] not in p_both for i in range(3)): continue sm = sum(int(s1[i]) + int(m[i]) + int(s2[i]) for i in range(3)) print(f"{s1}\n{m} with sum {sm}\n{s2}\n ")LikeLike
GeoffR 8:12 pm on 2 June 2023 Permalink |
# reusing first part of Frits' code P = [3, 5, 7] P += [x for x in range(11, 33, 2) if all(x % p for p in P)] P = [str(x) for x in range(101, 1000, 2) if all(x % p for p in P)] # a list of all valid reversed prime numbers - only 22 no. p_both = [str(p) for p in P if len(set(p)) == 3 and p[::-1] in P] # grid # a b c = prime q1 # d e f = prime q2 # g h i = prime q3 from enigma import all_different from itertools import permutations for p1 in permutations(p_both, 3): q1, q2, q3 = p1 # find digits in L.H. column a, d, g = q1[0], q2[0], q3[0] adg, gda = a + d + g, g + d + a if adg in p_both and gda in p_both: # find digits in middle column b, e, h = q1[1], q2[1], q3[1] beh, heb = b + e + h, h + e + b if beh in p_both and heb in p_both: # find digits in R.H. column c, f, i = q1[2], q2[2], q3[2], cfi, ifc = c + f + i, i + f + c if cfi in p_both and ifc in p_both: # check all rows and columns are different if all_different(q1, q2, q3, adg, beh, cfi): print(q1); print(q2); print(q3) # find total of all digits in the grid total = sum(int(i) for i in (a,b,c,d,e,f,g,h,i)) print('Total of all digits = ', total) print() # 937 # 743 # 179 # Total of all digits = 50LikeLike
Frits 1:39 pm on 3 June 2023 Permalink |
or
from itertools import permutations # 143 prime numbers between 100 and 1000 P = [3, 5, 7] P += [x for x in range(11, 33, 2) if all(x % p for p in P)] P = [str(x) for x in range(101, 1000, 2) if all(x % p for p in P)] # a list of all valid prime numbers p_both = [p for p in P if len(set(p)) == 3 and p[::-1] in P] for p in permutations(p_both, 3): # transpose the permutations to get the columns if any(''.join(col) not in p_both for col in zip(*p)): continue print('\n'.join(p)) print("sum = ", sum(int(y) for x in p for y in x), "\n")LikeLike
GeoffR 2:56 pm on 3 June 2023 Permalink |
% A Solution in MiniZinc include "globals.mzn"; % a b c % d e f % g h i % Reversible primes can only start or end with 1,3,7 ot 9. set of int: pr = {1,3,7,9}; var pr:a; var pr:b; var pr:c; var pr:d; var 0..9:e; var pr:f; var pr:g; var pr:h; var pr:i; % Reversible primes, as found in the Python solution set of int: primes = {107, 149, 157, 167, 179, 347, 359, 389, 701, 709, 739, 743, 751, 761, 769, 907, 937, 941, 953, 967, 971, 983}; % Reversible prime rows and columns constraint (100*a + 10*b + c) in primes; constraint (100*c + 10*b + a) in primes; constraint (100*d + 10*e + f) in primes; constraint (100*f + 10*e + d) in primes; constraint (100*g + 10*h + i) in primes; constraint (100*i + 10*h + g) in primes; constraint (100*a + 10*d + g) in primes; constraint (100*g + 10*d + a) in primes; constraint (100*b + 10*e + h) in primes; constraint (100*h + 10*e + b) in primes; constraint (100*c + 10*f + i) in primes; constraint (100*i + 10*f + c) in primes; % all rows and columns are different constraint all_different([ (100*a + 10*b + c) , (100*d + 10*e + f), (100*g + 10*h + i), (100*a + 10*d + g), (100*b + 10*e + h), (100*c + 10*f + i)]); solve satisfy; output[ show(a), show(b),show(c) ++ "\n" ++ show(d),show(e),show(f) ++ "\n" ++ show(g),show(h),show(i) ++ "\nDigit total = " ++ show(a+b+c+d+e+f+g+h+i)];LikeLike