/* Reversed cryptograms in Picat. Find the minimum construction of the following: - length of x = n - digits 0..9 - all_different(x) - all_different(z) - x + reversed(x) = z - x[1] > 0 and x[n] > 0 How many optimal solutions are there for different n? With symmetry breaking x[1] < x[n]: n #sols -------- 1 = 0 2 = 0 3 = 42 4 = 260 5 = 584 6 = 504 7 = 1648 8 = 2016 9 = 992 10 = 1152 Without symmetry breaking: n #sols -------- 1 = 4 2 = 0 3 = 84 4 = 520 5 = 1168 6 = 1008 7 = 3296 8 = 4032 9 = 1984 10 = 2304 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 = 10, println(n=N), crypt_reversed(N, X,Xrev,Z), println('x '=X), println(xrev=Xrev), println('z '=Z), nl, fail, nl. go => true. % % Number of solutions for N=1..10. % As the problem is constructed, there can be no solution for % N > 10 (since the domain is 0..9). % go2 => foreach(N in 1..10) Count = count_all(crypt_reversed(N, _X,_Xrev,_Z)), println(N=Count) end, nl. crypt_reversed(N, X,Xrev,Z) => X = new_list(N), X :: 0..9, Xrev = new_list(N), Xrev :: 0..9, % sum of x + reversed(x) Z = new_list(N), Z ::0..9, VX :: 10**(N-1)..10**N-1, VZ :: 10**(N-1)..10**N-1, all_different(X), all_different(Z), to_num(X,10,VX), to_num(Z,10,VZ), % VZ #= VX + to_num(reverse_list(X)), % this don't work Xrev = reverse_list(X), VX2 = to_num(Xrev), % Note: not #= ! VZ #= VX + VX2, X[1] #> 0, X[N] #> 0, Z[1] #> 0, % symmetry breaking X[1] #< X[N], Vars = X ++ Xrev ++ Z ++ [VX,VX2,VZ], solve($[ff,split],Vars). % % 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]). to_num(List) = Num => Len = length(List), Num #= sum([List[I]*10**(Len-I) : I in 1..Len]). % returns the reversed array of a reverse_list(A,B) => N = A.len, foreach(I in 1..N) B[I] #= A[N-I+1] end. % reverse list as a function reverse_list(A) = B => N = A.len, B = new_list(N), foreach(I in 1..N) B[I] #= A[N-I+1] end.