/* Rookwise chain puzzle in Picat. Martin Gardner (June 1961) """ [P]lace the digits [1..9] on a 3 x 3 matrix so that they form a rookwise connected chain, from 1 to 9, and also in such a way that the bottom row is the sum of the first two rows. The answer is unique. """ Solution: [1,2,9] [4,3,8] [5,6,7] row_sums = [129,438,567] This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go => N = 3, X = new_array(N,N), X :: 1..N*N, RowSums = new_list(N), RowSums :: 123..999, foreach(I in 1..N) RowSums[I] #> 0 end, all_different(X), % sum of rows foreach(I in 1..N) to_num([X[I,J] : J in 1..N],10, RowSums[I]) end, % sum of first 1..n-1 rows = n'th row RowSums[N] #= sum([RowSums[I] : I in 1..N-1]), % the rook moves foreach(K in 1..N*N-1) sum([ K #= X[I,J] % fix this k #/\ % find the next k sum([K+1 #= X[I+A,J+B] : A in [-1,0,1], B in [-1,0,1], I+A >= 1, J+B >= 1, I+A <= N, J+B <= N, abs(A+B) == 1 % just move in exactly one direction ]) #> 0 : I in 1..N, J in 1..N ]) #> 0 end, Vars = X.vars ++ RowSums, solve($[ffd,split],Vars), foreach(Row in X) println(Row.to_list) end, println(row_sums=RowSums), nl, fail, nl. % % converts a number Num to/from a list of integer List given a base Base % to_num(List, Base, Num) => Len = length(List), Num #= sum([List[I]*Base**(Len-I) : I in 1..Len]).