/* Enigma 430: Let your fingers do the walking in Picat. https://enigmaticcode.wordpress.com/2018/01/05/enigma-430-let-your-fingers-do-the-walking/ """ From New Scientist #1580, 1st October 1987 [link] My Welsh friend, Dai the dial, has a telephone number consisting of nine different digits and, as you telephone him on my push-button phone illustrated above, you push a sequence of buttons each adjacent (across or down) to the one before. 1 2 3 4 5 6 7 8 9 0 The digit not used in his number is odd, the last digit of the number is larger than the first, and (ignoring the leading digit if it is zero) the number is divisible by 21. What is Dai's number? """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp,util. main => go. go ?=> % nolog, N = 9, Dial = [ [8], % 0 [2,4], % 1 [1,3,4], % 2 [2,6], % 3 [1,5,7], % 4 [2,4,6,8], % 5 [3,5,9], % 6 [4,8], % 7 [5,7,9,0], % 8 [6,8] % 9 ], % convert Dial to a matrix DialMatrix = new_array(10,10), bind_vars(DialMatrix,0), foreach({I,Digits} in zip(0..9,Dial)) foreach(D in Digits) DialMatrix[I+1,D+1] := 1 end end, X = new_list(N), X :: 0..9, all_different(X), X[1] #< X[N], % domains of X foreach(I in 2..N) XI1 #= X[I-1] + 1, XI #= X[I] + 1, matrix_element(DialMatrix,XI,XI1,1) end, NotUsed :: 0..9, NotUsed mod 2 #= 1, foreach(I in 1..N) NotUsed #!= X[I] end, Num #> 0, to_num(X,10,Num), Num mod 21 #= 0, Vars = X ++ [Num,NotUsed], solve($[degree,split],Vars), println([I.to_string() : I in X].join('')), println(notUsed=NotUsed), fail, % ensure unicity nl. go => true. % % 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]).