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