/* Binary puzzle in Picat. From http://stackoverflow.com/questions/27421360/binary-puzzle-check """ The rules are: - Every cell must be a 1 or 0 - It's not allowed to get 3 of the same values next to each other or under/above each other. - Every row and column needs to have a even numbers of 1 and 0, so in case of a 6 by 6 board, a row/column must have 3 1s and 3 0s """ For N = 6, there are 11222 different solutions, e.g. X: [0,0,1,0,1,1] [0,0,1,0,1,1] [1,1,0,1,0,0] [0,0,1,0,1,1] [1,1,0,1,0,0] [1,1,0,1,0,0] X: [0,0,1,0,1,1] [0,0,1,0,1,1] [1,1,0,1,0,0] [0,0,1,1,0,1] [1,1,0,0,1,0] [1,1,0,1,0,0] 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 = 6, binary_puzzle(N,X), println("X:"), foreach(Row in X) println(Row.to_list) end, nl, fail, nl. /* Number of solutions for N=1..9 1: 1 2: 2 3: 6 4: 90 5: 34 6: 11222 7: 8908 8: 12413918 9: 14782856 Not in OEIS Separate into odd and even: 1,6,34,8908 : not in OEIS 2,90,112222 : not in OEIS */ go2 => foreach(N in 1..9) Count = count_all(binary_puzzle(N,_X)), printf("%2d: %d\n",N,Count) end, nl. binary_puzzle(N, X) => M = N div 2, X = new_array(N,N), X :: 0..1, foreach(I in 1..N) ThisRow = [X[I,J] : J in 1..N], ThisColumn = [X[J,I] : J in 1..N], % same number of 0..1 in rows and columns sum(ThisRow) #= M, sum(ThisColumn) #= M, % no 3 0's or 1's in a row/column % -> Require that the sum of the 3-slices of a row/column % is either 1 or 2 sliding_sum(1,2,3,ThisRow), sliding_sum(1,2,3,ThisColumn) end, % symmetry breaking % X[1,1] #= 0, solve(X). % From sliding_sum.pi % % Note: Seq must be instantiated, but neither Low or Up has % to be (the result may be weird unless they are, though). % sliding_sum(Low, Up, Seq, Variables) => foreach(I in 1..Variables.length-Seq+1) Sum #= sum([Variables[J] : J in I..I+Seq-1]), Sum #>= Low, Sum #=< Up end.