Download
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"];