如何更好地解决“破解代码”逻辑难题

时间:2018-12-06 13:24:11

标签: prolog

我尝试为Can You Crack The Code? “Only Geniuses Can Solve”编写Prolog解决方案。

为方便起见,我在此处复制文本:

  

数字锁需要一个3位数字的密码。根据这些提示:

     

682 –一个数字正确且位置正确

     

645 –一个数字正确但位置错误

     

206 –两个数字正确但位置错误

     

738 –没错

     

780 –一个数字正确但位置错误

     

您可以破解代码吗?

A为每种提示提供了一个谓词。

对于“一个数字正确且位置正确”的提示,我写道:

correct_position(A, B, C, S) :-
    S = [A, _, _],
    \+ member(B, S),
    \+ member(C, S).
correct_position(A, B, C, S) :-
    S = [_, B, _],
    \+ member(A, S),
    \+ member(C, S).
correct_position(A, B, C, S) :-
    S = [_, _, C],
    \+ member(A, S),
    \+ member(B, S).

对于“一个数字正确但位置错误”的提示,我写道:

wrong_position(A, B, C, S) :-
    (S = [_, A, _] ; S = [_, _, A]),
    \+ member(B, S),
    \+ member(C, S).
wrong_position(A, B, C, S) :-
    (S = [B, _, _] ; S = [_, _, B]),
    \+ member(A, S),
    \+ member(C, S).
wrong_position(A, B, C, S) :-
    (S = [C, _, _] ; S = [_, C, _]),
    \+ member(A, S),
    \+ member(B, S).

对于“两个数字是正确的但位置错误”的提示,我写道:

two_wrong_position(A, B, C, S) :-
    S \= [A, _, _],
    S \= [_, B, _],
    member(A, S),
    member(B, S),
    \+ member(C, S).
two_wrong_position(A, B, C, S) :-
    S \= [A, _, _],
    S \= [_, _, C],
    member(A, S),
    member(C, S),
    \+ member(B, S).
two_wrong_position(A, B, C, S) :-
    S \= [_, B, _],
    S \= [_, _, C],
    member(B, S),
    member(C, S),
    \+ member(A, S).

最后,我写了“什么都不对”的提示:

none(A, B, C, S) :-
    \+ member(A, S),
    \+ member(B, S),
    \+ member(C, S).

然后获得解决方案:

solution(S) :-
    between(0, 9, A),
    between(0, 9, B),
    between(0, 9, C),
    S = [A, B, C],
    correct_position(6, 8, 2, S),
    wrong_position(6, 4, 5, S),
    two_wrong_position(2, 0, 6, S),
    none(7, 3, 8, S),
    wrong_position(7, 8, 0, S).

当然可以,但是提示的谓词是对问题实例的“硬编码”,根本无法扩展。错误位置和two_wrong_positions谓词说明的情况相似,但完全不同,并且在出现新问题的情况下,给出了“三个数字正确但位置错误”的提示,必须从头开始将其编码。

如何重写此类提示的谓词?

0 个答案:

没有答案