alpar@1: /* MAGIC, Magic Square */ alpar@1: alpar@1: /* Written in GNU MathProg by Andrew Makhorin */ alpar@1: alpar@1: /* In recreational mathematics, a magic square of order n is an alpar@1: arrangement of n^2 numbers, usually distinct integers, in a square, alpar@1: such that n numbers in all rows, all columns, and both diagonals sum alpar@1: to the same constant. A normal magic square contains the integers alpar@1: from 1 to n^2. alpar@1: alpar@1: (From Wikipedia, the free encyclopedia.) */ alpar@1: alpar@1: param n, integer, > 0, default 4; alpar@1: /* square order */ alpar@1: alpar@1: set N := 1..n^2; alpar@1: /* integers to be placed */ alpar@1: alpar@1: var x{i in 1..n, j in 1..n, k in N}, binary; alpar@1: /* x[i,j,k] = 1 means that cell (i,j) contains integer k */ alpar@1: alpar@1: s.t. a{i in 1..n, j in 1..n}: sum{k in N} x[i,j,k] = 1; alpar@1: /* each cell must be assigned exactly one integer */ alpar@1: alpar@1: s.t. b{k in N}: sum{i in 1..n, j in 1..n} x[i,j,k] = 1; alpar@1: /* each integer must be assigned exactly to one cell */ alpar@1: alpar@1: var s; alpar@1: /* the magic sum */ alpar@1: alpar@1: s.t. r{i in 1..n}: sum{j in 1..n, k in N} k * x[i,j,k] = s; alpar@1: /* the sum in each row must be the magic sum */ alpar@1: alpar@1: s.t. c{j in 1..n}: sum{i in 1..n, k in N} k * x[i,j,k] = s; alpar@1: /* the sum in each column must be the magic sum */ alpar@1: alpar@1: s.t. d: sum{i in 1..n, k in N} k * x[i,i,k] = s; alpar@1: /* the sum in the diagonal must be the magic sum */ alpar@1: alpar@1: s.t. e: sum{i in 1..n, k in N} k * x[i,n-i+1,k] = s; alpar@1: /* the sum in the co-diagonal must be the magic sum */ alpar@1: alpar@1: solve; alpar@1: alpar@1: printf "\n"; alpar@1: printf "Magic sum is %d\n", s; alpar@1: printf "\n"; alpar@1: for{i in 1..n} alpar@1: { printf{j in 1..n} "%3d", sum{k in N} k * x[i,j,k]; alpar@1: printf "\n"; alpar@1: } alpar@1: printf "\n"; alpar@1: alpar@1: end;