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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | % % Magic squares in MiniZinc % % % This MiniZinc model was created by Hakan Kjellerstrand, hakank@gmail.com % See also my MiniZinc page: http://www.hakank.org/minizinc % % Licenced under CC-BY-4.0 : http://creativecommons.org/licenses/by/4.0/ include "globals.mzn" ; int : n = 3; int : total = ( n * (n * n + 1)) div 2; array [1 .. n,1 .. n] of var 1 .. n * n: magic; % solve satisfy; solve :: int_search( [magic[i,j] | i in 1 .. n, j in 1 .. n], first_fail, indomain_min, complete) satisfy ; constraint all_different([magic[i,j] | i in 1 .. n, j in 1 .. n]) :: domain /\ forall(k in 1 .. n) ( sum (i in 1 .. n) (magic[k,i]) = total % :: domain /\ sum (i in 1 .. n) (magic[i,k]) = total %:: domain ) /\ % diagonal sum (i in 1 .. n) (magic[i,i]) = total %:: domain /\ % diagonal sum (i in 1 .. n) (magic[i,n - i + 1]) = total %:: domain ; % symmetry breaking % Activating all these constraints we get the % "standard" way of counting the number of solutions: % 1, 0, 1, 880, 275305224 % i.e. this sequence: http://oeis.org/A006052 % % Without the constraints the number of solutions are: % N #solutions % ------------- % 1 1 % 2 0 % 3 8 % 4 7040 % 5 many... % % constraint % magic[1,1] < magic[1,n] % /\ magic[1,n] < magic[n,1] % /\ magic[1,1] < magic[n,n] % ; output [ "Total: " ++ show (total) ++ "\n" ] ++ [ % show(magic) if j = 1 then "\n" else "" endif ++ if fix (magic[i,j]) < 10 then " " else "" endif ++ show (magic[i,j]) ++ " " | i,j in 1 .. n ] ++ [ "\n" ]; |