/* 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).