A friend from work shared this with our whatsapp group:
This lock has a 3 digit code.
Can you guess it using only these hints?
We solved it using something akin to a truth table. I'm curious however, how would this be solved in Prolog?
Straightforward coding of the check predicate:
check( Solution, Guess, NValues, NPlaces ) :- Solution = [A,B,C], Guess = [X,Y,Z], findall( t, (member(E, Guess), member(E, Solution)), Values ), length( Values, NValues ), ( A=X -> V1 is 1 ; V1 is 0 ), ( B=Y -> V2 is 1+V1 ; V2 is V1 ), ( C=Z -> NPlaces is 1+V2 ; NPlaces is V2 ).
Then simply transcribe the clues, no creativity involved:
puzzle( [A,B,C] ):- findall( X, between(0,9,X), XS ), select(A,XS,RA), select(B,RA,RB), member(C,RB), /* "291": one digit is right and in its place "245": one digit is right but in the wrong place "463": two digits are right but both are in the wrong place "578": all digits are wrong "569": one digit is right but in the wrong place */ check( [A,B,C], [2,9,1], 1, 1 ), check( [A,B,C], [2,4,5], 1, 0 ), check( [A,B,C], [4,6,3], 2, 0 ), check( [A,B,C], [5,7,8], 0, 0 ), check( [A,B,C], [5,6,9], 1, 0 ).
23 ?- time( puzzle(X) ). /* 13,931 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips) */ X = [3, 9, 4] ; /* 20,671 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips) */ false.