Brain-Teaser 905: Prime square
From The Sunday Times, 25th November 1979 [link]
“Here”, said Uncle Henry to the twins, “is a magic square which I’ve started for you”:
“You must complete it by putting eight different prime numbers in the eight empty squares, so that the [rows], the columns and the diagonals add up to the same total; and it must be the smallest possible total under the conditions.”
There followed half an hour of comparative peace… after which the twins could bear it no longer.
“Oh. Uncle”, complained Betty, “It looks so easy and yet it’s much too difficult”. And Brian fervently agreed.
“All right”, said Uncle Henry, “I’ll tell you a couple more things: there is one such magic square where the number in the middle square is the average of the two numbers directly above and below it; the third largest number is not in the right-hand column; and each square contains one or two digits”.
After a further ten minutes, the twins managed to produce the right solution.
Can you complete the magic square?
This puzzle is included in the book The Sunday Times Book of Brain-Teasers: Book 1 (1980). The puzzle text above is taken from the book.
It is also included in the book The Sunday Times Book of Brainteasers (1994).
[teaser905]

Jim Randell 10:17 am on 28 October 2021 Permalink |
We can use the [[
SubstitutedExpression]] solver from the enigma.py library to solve this puzzle.The following run file executes in 64ms.
Run: [ @replit ]
#! python3 -m enigma -rr # AB CD EF # GH IJ KL # MN 01 PQ SubstitutedExpression --distinct="" --invalid="" # missing numbers are different 1 or 2 digit primes "is_prime(AB)" "is_prime(CD)" "is_prime(EF)" "is_prime(GH)" "is_prime(IJ)" "is_prime(KL)" "is_prime(MN)" "is_prime(PQ)" "all_different(AB, CD, EF, GH, IJ, KL, MN, PQ)" # in an additive magic square the magic constant is 3 times the centre value (= 3 * IJ) "2 * IJ - 1 = CD" "2 * IJ - AB = PQ" "2 * IJ - EF = MN" "2 * IJ - GH = KL" "3 * IJ - AB - CD = EF" "3 * IJ - MN - 1 = PQ" "3 * IJ - AB - GH = MN" "3 * IJ - EF - KL = PQ" # third largest number is _not_ in the RH column "ordered(1, AB, CD, EF, GH, IJ, KL, MN, PQ)[-3] not in {EF, KL, PQ}" --template="(AB CD EF) (GH IJ KL) (MN 01 PQ)" --solution=""Solution: Here is a diagram of the completed square:
LikeLike
Mark Valentine 1:21 pm on 28 October 2021 Permalink |
Third largest number can’t be in right-hand column. Need to flip it.
LikeLike
Mark Valentine 1:23 pm on 28 October 2021 Permalink |
Apologies. Misread it. Yours is correct.
LikeLike
Frits 3:41 pm on 28 October 2021 Permalink |
Using “3 * IJ – AB – MN = GH” instead of “3 * IJ – AB – GH = MN” you don’t have to internally loop over G and H.
LikeLike
Jim Randell 12:35 pm on 29 October 2021 Permalink |
And here is a Python program that can be used to generate magic squares with larger magic constants:
from enigma import primes, ordered, arg, printf # the magic square is: # # A B C # D E F # G 1 H # # so the magic constant k = 3E # generate magic squares def generate(): # consider values for E for E in primes.range(3): k = 3 * E B = k - E - 1 if B not in primes: continue # choose a value for A for A in primes.range(3, k - E): # calculate the remaining values H = k - A - E if H not in primes: continue C = k - A - B if C not in primes: continue F = k - C - H if F not in primes: continue G = k - C - E if G + 1 + H != k or G not in primes: continue D = k - E - F if A + D + G != k or D not in primes: continue # check conditions if len({A, B, C, D, E, F, G, H}) != 8: continue ns = ordered(A, B, C, D, E, F, G, 1, H) if ns[-3] in {C, F, H}: continue # valid layout yield (A, B, C, D, E, F, G, H) N = arg(1, 0, int) for (n, (A, B, C, D, E, F, G, H)) in enumerate(generate(), start=1): printf("[ {A} {B} {C} | {D} {E} {F} | {G} 1 {H} ] {k}", k=3 * E) if n == N: breakLikeLike
Hugh Casement 2:47 pm on 28 October 2021 Permalink |
It’s superfluous information (though perhaps helpful) that the middle column is an arithmetic progression.
Rather than say “the third largest number is not in the right-hand column” it would have been simpler to tell us that the smallest prime is in the left-hand column (otherwise we find a reflection in the vertical axis).
Without the 1 we would need at least two 3-digit primes to make a magic square.
LikeLike
GeoffR 4:12 pm on 28 October 2021 Permalink |
My solution shows that the 3rd highest number must not be in the right hand column is a definite requirement, as shown in the note at the end of the programme output. I initially wrote a programme without this constraint. I am not sure how this constraint would be programmed in MiniZinc.
LikeLike
Frits 10:28 am on 29 October 2021 Permalink |
@GeoffR, you can declare an array, fill it with same elements as the original array and add an “increasing” constraint.
% A Solution in MiniZinc include "globals.mzn"; % A B C % D E F % G H I var 2..97:A; var 2..97:B; var 2..97:C; var 2..97:D; var 2..97:E; var 2..97:F; var 2..97:G; var 2..97:I; int: H == 1; constraint all_different([A, B, C, D, E, F, G, H, I]); array[1..9] of var 1..97: nbrs = [A, B, C, D, E, F, G, H, I]; array[1..9] of var 1..97: sorted; % make sure both arrays contain same elements constraint forall(X in nbrs)( exists(i in 1..9) ( X = sorted[i]) ); % make sure array "sorted" is sorted constraint increasing(sorted); predicate is_prime(var int: x) = x > 1 /\ forall(i in 2..1 + ceil(sqrt(int2float(ub(x))))) ((i < x) -> (x mod i > 0)); % All values of the grid (except H) are primes constraint is_prime(A) /\ is_prime(B) /\ is_prime(C) /\ is_prime(D) /\ is_prime(E) /\ is_prime(F) /\ is_prime(G) /\ is_prime(I); % All rows, columns and diagonals add to the same total constraint A + B + C == D + E + F /\ A + B + C == G + H + I /\ A + B + C == A + D + G /\ A + B + C == B + E + H /\ A + B + C == C + F + I /\ A + B + C == A + E + I /\ A + B + C == C + E + G; % the middle square is the average of the two numbers % directly above and below it constraint 2 * E == B + H; % third largest number is not in the RH column constraint C != sorted[7] /\ F != sorted[7] /\ I != sorted[7]; % the smallest possible total solve minimize(A + B + C); output [show([A,B,C]) ++ "\n" ++ show([D,E,F]) ++ "\n" ++ show([G, H, I])];LikeLike
GeoffR 11:00 am on 29 October 2021 Permalink |
@Frits:
Yes, that is a neat solution to ensure that the third largest number is not in the right-hand column.
LikeLike