/* Number lock problem in Picat. From Presh Talwalkar (MindYourDecisions) """ Puzzles like this have been shared with the dubious claim that "only a genius can solve" them. But they are still fun problems so let's work one out. A number lock requires a 3 digit code. Based on these hints, can you crack the code? 682 - one number is correct and in the correct position 645 - one number is correct but in the wrong position 206 - two numbers are correct but in the wrong positions 738 - nothing is correct 780 - one number is correct but in the wrong position Video: https://youtu.be/-etLb-8sHBc """ Also: Are all constraints really needed? See below. This Picat model 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 ?=> N = 3, % number of digits Y = [ [6,8,2], % - one number is correct and in the correct position [6,4,5], % - one number is correct but in the wrong position [2,0,6], % - two numbers are correct but in the wrong positions [7,3,8], % - nothing is correct [7,8,0] % - one number is correct but in the wrong position ], % decision variables X = new_list(N), X :: 0..9, % Testing a different number combination (get the #correct pos and #correct values TPos :: 0..N, TVal :: 0..N, % 682 - one number is correct and in the correct position check([Y[1,J] : J in 1..N],X,1,1), % 645 - one number is correct but in the wrong position check([Y[2,J] : J in 1..N],X,0,1), % 206 - two numbers are correct but in the wrong positions check([Y[3,J] : J in 1..N],X,0,2), % 738 - nothing is correct % Note: This is not really needed. But if we remove this and the next % constraint the solver has to backtrack. check([Y[4,J] : J in 1..N],X,0,0), % 780 - one number is correct but in the wrong position % Note: This constraint is not really needed. % And the solve don't have to backtrack if it's removed. check([Y[5,J] : J in 1..N],X,0,1), % Testing another number to get the correct number of posistions/values check([1,2,3],X,TPos,TVal), Vars = X ++ [TPos, TVal], solve($[],Vars), println(X), println([tpos=TPos,tval=TVal]), fail, nl. go => true. % How many % pos: correct values and positions % val: correct values (regardless if there are correct position or not) check(A, B, Pos, Val) => N = A.len, % number of entries in correct position (and correct values) sum([A[J] #= B[J] : J in 1..N]) #= Pos, % number of entries which has correct values (regardless if there are in correct position or not) sum([A[J] #= B[K] : J in 1..N, K in 1..N ]) #= Val.