rev |
line source |
alpar@9
|
1 /* MAGIC, Magic Square */
|
alpar@9
|
2
|
alpar@9
|
3 /* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */
|
alpar@9
|
4
|
alpar@9
|
5 /* In recreational mathematics, a magic square of order n is an
|
alpar@9
|
6 arrangement of n^2 numbers, usually distinct integers, in a square,
|
alpar@9
|
7 such that n numbers in all rows, all columns, and both diagonals sum
|
alpar@9
|
8 to the same constant. A normal magic square contains the integers
|
alpar@9
|
9 from 1 to n^2.
|
alpar@9
|
10
|
alpar@9
|
11 (From Wikipedia, the free encyclopedia.) */
|
alpar@9
|
12
|
alpar@9
|
13 param n, integer, > 0, default 4;
|
alpar@9
|
14 /* square order */
|
alpar@9
|
15
|
alpar@9
|
16 set N := 1..n^2;
|
alpar@9
|
17 /* integers to be placed */
|
alpar@9
|
18
|
alpar@9
|
19 var x{i in 1..n, j in 1..n, k in N}, binary;
|
alpar@9
|
20 /* x[i,j,k] = 1 means that cell (i,j) contains integer k */
|
alpar@9
|
21
|
alpar@9
|
22 s.t. a{i in 1..n, j in 1..n}: sum{k in N} x[i,j,k] = 1;
|
alpar@9
|
23 /* each cell must be assigned exactly one integer */
|
alpar@9
|
24
|
alpar@9
|
25 s.t. b{k in N}: sum{i in 1..n, j in 1..n} x[i,j,k] = 1;
|
alpar@9
|
26 /* each integer must be assigned exactly to one cell */
|
alpar@9
|
27
|
alpar@9
|
28 var s;
|
alpar@9
|
29 /* the magic sum */
|
alpar@9
|
30
|
alpar@9
|
31 s.t. r{i in 1..n}: sum{j in 1..n, k in N} k * x[i,j,k] = s;
|
alpar@9
|
32 /* the sum in each row must be the magic sum */
|
alpar@9
|
33
|
alpar@9
|
34 s.t. c{j in 1..n}: sum{i in 1..n, k in N} k * x[i,j,k] = s;
|
alpar@9
|
35 /* the sum in each column must be the magic sum */
|
alpar@9
|
36
|
alpar@9
|
37 s.t. d: sum{i in 1..n, k in N} k * x[i,i,k] = s;
|
alpar@9
|
38 /* the sum in the diagonal must be the magic sum */
|
alpar@9
|
39
|
alpar@9
|
40 s.t. e: sum{i in 1..n, k in N} k * x[i,n-i+1,k] = s;
|
alpar@9
|
41 /* the sum in the co-diagonal must be the magic sum */
|
alpar@9
|
42
|
alpar@9
|
43 solve;
|
alpar@9
|
44
|
alpar@9
|
45 printf "\n";
|
alpar@9
|
46 printf "Magic sum is %d\n", s;
|
alpar@9
|
47 printf "\n";
|
alpar@9
|
48 for{i in 1..n}
|
alpar@9
|
49 { printf{j in 1..n} "%3d", sum{k in N} k * x[i,j,k];
|
alpar@9
|
50 printf "\n";
|
alpar@9
|
51 }
|
alpar@9
|
52 printf "\n";
|
alpar@9
|
53
|
alpar@9
|
54 end;
|