/* Self-counting sentence in Picat. From Adrian Groza "Modelling Puzzles in First Order Logic" """ Puzzle 144. Self-counting sentence Insert numbers in the blanks to make this sentence true: In this sentence, the number of occurrences of 0 is __, of 1 is __, of 2 is __, of 3 is __, of 4 is __, of 5 is _, of 6 is __, of 7 is __, of 8 is __, and of 9 is _. There are exactly two solutions. """ The two solutions are * s1/0 s = [1,7,3,2,1,1,1,2,1,1] In this sentence, the number of occurrences of 0 is 1, of 1 is 7, of 2 is 3, of 3 is 2, of 4 is 1 of 5 is 1 of 6 is 1, of 7 is 2, of 8 is 1, and of 9 is 1. This is a CP version using count/3 * s2/0 [[0,1],[1,11],[2,2],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1]] In this sentence, the number of occurrences of 0 is 1, of 1 is 11, of 2 is 2, of 3 is 1, of 4 is 1 of 5 is 1 of 6 is 1, of 7 is 1, of 8 is 1, and of 9 is 1. This is an imperative variant. Note that it does only finds this solution, not the one in s1/0. This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. import cp. main => go. go => s1, s2, nl. % % This is one of the two solutions: % [1,7,3,2,1,1,1,2,1,1] % % Note: The second solution it finds: % [1,10,1,1,1,1,1,1,1,1] % is almost correct but not fully correct since it does take into account % the 10 includes one "1" and 1 "0". % % Hence the s2/0 version below. % s1 => N = 10, X = new_list(N), X :: 0..N, foreach(I in 0..N-1) X[I+1] #= 1+count(I,X) end, solve(X), println(X), printf("In this sentence, the number of occurrences of 0 is %d, of 1 is %d, of 2 is %d, of 3 is %d, of 4 is %d of 5 is %d of 6 is %d, of 7 is %d, of 8 is %d, and of 9 is %d.\n",X[1],X[2],X[3],X[4],X[5],X[6],X[7],X[8],X[9],X[10]), nl, % fail, % it also finds a not fully correct version nl. % % This is the other solution: % [[0,1],[1,11],[2,2],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1]] % % It finds the stable solution in three steps: % s = [[0,1],[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1]] % s = [[0,1],[1,12],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1]] % s = [[0,1],[1,11],[2,2],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1]] % % However, it does not find the solution in s1/0. % s2 => S = seq([0,1,2,3,4,5,6,7,8,9]), println(S), printf("In this sentence, the number of occurrences of 0 is %d, of 1 is %d, of 2 is %d, of 3 is %d, of 4 is %d of 5 is %d of 6 is %d, of 7 is %d, of 8 is %d, and of 9 is %d.\n",S[1,2],S[2,2],S[3,2],S[4,2],S[5,2],S[6,2],S[7,2],S[8,2],S[9,2],S[10,2]), fail, nl. count_seq(S,N) = T => SS = S.flatten.map(to_string).flatten.map(to_int), T = new_list(N), foreach(I in 0..N-1) T[I+1] = [I,[V : V in SS, V == I].len] end. seq(L) = Found => N = 10, S = count_seq(L,N), Found = false, while (Found == false) % println(s=S), % Showing the steps T = count_seq(S,N), if S == T then Found := S else S := count_seq(T,N) end end.