/* Scanner problem in Picat. Problem from Sverker Jansson "AKL - A Multiparadigm Programming Language", page 176 """ The problem is to reveal the contents of a grid. Each square may be filled or non-filled. The input is the number of filled squares along each row, column, and diagonal. In general, there may be no, one, or several solutions for a given input. """ The unique solution of the problem instance is a cat: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util,cp. main => go. go => Rows = [1,13,17,17,14,14,12,6,6,6], NumRows = Rows.len, Columns = [2,1,1,3,3,6,6,8,9,7,5,5,5,5,6,8,8,8,4,4,2], NumCols = Columns.len, % Upper-left to lower-right diagonals Diagonal1 = [0,0,0,0,0,1,2,5,6,4,4,6,7,7,8,8,5,6,6,6,6,5,5,3,3,1,1,1,0,0], NumDiagonal1 = Diagonal1.len, % Upper-right to lower-left diagonals Diagonal2 = [0,1,2,3,3,3,2,4,5,5,7,9,9,6,6,5,4,5,5,4,5,4,2,2,2,2,1,0,0,0], NumDiagonal2 = Diagonal2.len, % Decision variables X = new_array(NumRows,NumCols), X :: 0..1, % rows foreach(I in 1..NumRows) sum([X[I,J] : J in 1..NumCols]) #= Rows[I] end, % columns foreach(J in 1..NumCols) sum([X[I,J] : I in 1..NumRows]) #= Columns[J] end, % diagonal1: Upper-left to lower-right diagonals foreach(K in 1..NumDiagonal1) sum([X[I,J] : I in 1..NumRows, J in 1..NumCols, I+J==K+1]) #= Diagonal1[K] end, % diagonal2: Upper-left to lower-right diagonals foreach(K in 1..NumDiagonal2) sum([X[I,J] : I in 1..NumRows, J in 1..NumCols, I+(NumCols-J+1)==K+1]) #= Diagonal2[K] end, solve(X), foreach(Row in X) printf("%w\n", [T : C in Row.to_list, T = cond(C == 1, "* "," ")].join('')) end, fail, nl.