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