/* Enigma problem 1553 (Squares from squares) in Picat. From New Scientist: """ Squares from squares Enigma 1553 Susan Denham, New Scientist magazine, July 11, 2009 Your task is to place a digit in each of these 16 squares: +--+--+--+--+ | | | | | +--+--+--+--+ | | | | | +--+--+--+--+ | | | | | +--+--+--+--+ | | | | | +--+--+--+--+ When you have finished, the grid should have the following properties: * no digit occurs more than once in any row * the sum of the four digits in each row is the same * the sum of the four digits in each column is the same * each row should form a different four-figure perfect square. Please send in the four perfect squares in increasing order. """ Compare with the Formula One model: http://www.f1compiler.com/samples/Enigma%201553.f1.html This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> N = 4, X = new_array(N,N), X :: 0..9, RowSum :: 0..10000, ColSum :: 0..10000, RowSquares = new_list(N), RowSquares :: 1000..9999, foreach(I in 1..N) % no digit occurs more than once in any row all_different(X[I]), % the sum of the four digits in each row is the same sum(X[I]) #= RowSum end, % * the sum of the four digits in each column is the same foreach(J in 1..N) sum([X[I,J] : I in 1..N]) #= ColSum end, % each row should form a different four-figure perfect square. foreach(I in 1..N) Y :: 1000..9999, to_num([X[I,J] : J in 1..N], 10, Y), square(Y), RowSquares[I] #= Y end, all_different(RowSquares), increasing(RowSquares), Vars = X.vars ++ RowSquares ++ [RowSum,ColSum], solve(Vars), println(rowSquares=RowSquares), foreach(Row in X) println(Row) end, println(rowSum=RowSum), println(colSum=ColSum), nl, fail, nl. go => true. % % Ensure that X is an square % square(X) => Max = fd_max(X), Y :: 0..ceiling(sqrt(Max)), Y*Y #= X. % % 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]).