/*
Heterosquare problem in Picat.
From http://willow.engr.uconn.edu/cometPubWiki/index.php/Heterosquare
"""
A heterosquare of order n is a n*n square whose elements are
distinct integers from 1 to n^2 such that the sums of the rows,
columns and diagonals are all different. Here is an example of
heterosquare of order 3
19
1 2 3 6
8 9 4 21
7 6 5 18
16 17 12 15 (Sums)
"""
Model created by Hakan Kjellerstrand, hakank@gmail.com
See also my Picat page: http://www.hakank.org/picat/
*/
import cp.
main => go.
go ?=>
N = 3,
heterosquare(N, Mat, RowSums, ColSums, Diag1, Diag2),
foreach(I in 1..N, J in 1..N)
writef("%3d ", Mat[I,J]),
if J == N then nl end
end,
writeln(rowsums=RowSums),
writeln(colsums=ColSums),
writeln(diag1=Diag1),
writeln(diag2=Diag2),
nl,nl,
fail.
go => true.
heterosquare(N, Mat, RowSums, ColSums, Diag1, Diag2) =>
Mat = new_array(N,N),
Mat :: 1..N*N,
MatVars = vars(Mat),
RowSums = new_list(N),
RowSums :: 1..N*N*N,
ColSums = new_list(N),
ColSums :: 1..N*N*N,
% diagonals
Diag1 :: 1..N*N*N,
Diag2 :: 1..N*N*N,
% all entries in the matrix should be different
all_different(MatVars),
% and all sums should be different
AllSums = RowSums ++ ColSums ++ [Diag1, Diag2],
all_different(AllSums),
% calculate rows sums
foreach(I in 1..N)
RowSums[I] #= sum([Mat[I,J] : J in 1..N])
end,
% calculate column sums
foreach(J in 1..N)
ColSums[J] #= sum([Mat[I,J] : I in 1..N])
end,
Diag1 #= sum([Mat[I,I] : I in 1..N]),
Diag2 #= sum([Mat[I,N-I+1] : I in 1..N]),
Vars = MatVars ++ RowSums ++ ColSums,
solve(Vars).