我想写一个prolog代码来解决以下游戏: Crack the 3 digit code based on these statements
这是我的第一个声明的代码:&#34;一个数字是正确的,位置很好&#34;,但我得到的答案是假的而不是[six,,],[< em>,8,],[,,两个]:
first(X, [X|_]).
second(X, [_,X,_]).
third(X, [_,_,X]).
one_correct_well([A,B,C], [X,Y,Z]):-first(A, [X,Y,Z]), B\=Y, C\=Z.
one_correct_well([A,B,C], [X,Y,Z]):-second(B, [X,Y,Z]), A\=X, C\=Z.
one_correct_well([A,B,C], [X,Y,Z]):-third(C, [X,Y,Z]), B\=Y, A\=X.
solution(CODE):-
CODE = [_,_,_],
one_correct_well([six,eight,two], CODE).
答案 0 :(得分:1)
以下结果为我[zero,four,two]
:
一位数字正确且位置优越:
对于[A,B,C],授权模式为:
[A,_,_]
[_,B,_]
[_,_,C]
因此以下代码:
one_correct_well([A,B,C],[A,X,Y]):-
delete([zero,one,two,three,four,five,six,seven,eight,nine],B,ListB),
member(X,ListB), % X can take any value different from B
delete([zero,one,two,three,four,five,six,seven,eight,nine],C,ListC),
member(Y,ListC). % Y can take any value different from C
one_correct_well([A,B,C],[X,B,Y]):-
delete([zero,one,two,three,four,five,six,seven,eight,nine],A,ListA),
member(X,ListA),
delete([zero,one,two,three,four,five,six,seven,eight,nine],C,ListC),
member(Y,ListC).
one_correct_well([A,B,C],[X,Y,C]):-
delete([zero,one,two,three,four,five,six,seven,eight,nine],A,ListA),
member(X,ListA),
delete([zero,one,two,three,four,five,six,seven,eight,nine],B,ListB),
member(Y,ListB).
一位数字正确但错误放置:
对于[A,B,C],授权模式为:
[_,A,_]
[_,_,A]
[B,_,_]
[_,_,B]
[C,_,_]
[_,C,_]
因此以下代码:
one_correct_wrong([A,B,C],[X,A,Y]):-
not_in2([X,Y],[A,B,C]).
one_correct_wrong([A,B,C],[X,Y,A]):-
not_in2([X,Y],[A,B,C]).
one_correct_wrong([A,B,C],[B,X,Y]):-
not_in2([X,Y],[A,B,C]).
one_correct_wrong([A,B,C],[X,Y,B]):-
not_in2([X,Y],[A,B,C]).
one_correct_wrong([A,B,C],[C,X,Y]):-
not_in2([X,Y],[A,B,C]).
one_correct_wrong([A,B,C],[X,C,Y]):-
not_in2([X,Y],[A,B,C]).
not_in2([X,Y],[A,B,C]):- % X and Y are different from A, B and C
delete([zero,one,two,three,four,five,six,seven,eight,nine],A,List1),
delete(List1,B,List2),
delete(List2,C,List3),
member(X,List3),
member(Y,List3).
修改强>
也许是一种更优雅的写作方式:
one_correct_wrong([A,B,C],L):-
(L=[X,A,Y]; % this, OR ..
L=[X,Y,A]; % .. this, OR ..
L=[B,X,Y]; % .. this, OR ..
L=[X,Y,B]; % .. this, OR ..
L=[C,X,Y]; % .. this, OR ..
L=[X,C,Y]),
not_in2([X,Y],[A,B,C]).
两位数字正确但错误放置:
two_correct_wrong([A,B,C],[B,A,X]):-
not_in(X,[A,B,C]).
two_correct_wrong([A,B,C],[B,X,A]):-
not_in(X,[A,B,C]).
two_correct_wrong([A,B,C],[X,A,B]):-
not_in(X,[A,B,C]).
two_correct_wrong([A,B,C],[X,C,B]):-
not_in(X,[A,B,C]).
two_correct_wrong([A,B,C],[C,X,B]):-
not_in(X,[A,B,C]).
two_correct_wrong([A,B,C],[B,C,X]):-
not_in(X,[A,B,C]).
two_correct_wrong([A,B,C],[C,X,A]):-
not_in(X,[A,B,C]).
two_correct_wrong([A,B,C],[C,A,X]):-
not_in(X,[A,B,C]).
two_correct_wrong([A,B,C],[X,C,A]):-
not_in(X,[A,B,C]).
not_in(X,[A,B,C]):- % X is different from A, B and C
delete([zero,one,two,three,four,five,six,seven,eight,nine],A,List1),
% List1 contains zero-nine without A
delete(List1,B,List2),
% List2 contains zero-nine without A and B
delete(List2,C,List3),
% List3 contains zero-nine without A, B and C
member(X,List3).
没有问题:
nothing_correct([A,B,C],[X,Y,Z]):-
delete([zero,one,two,three,four,five,six,seven,eight,nine],A,ListA),
delete(ListA,B,ListB),
delete(ListB,C,ListC),
member(X,ListC),
member(Y,ListC),
member(Z,ListC).
<强>解决方案:强>
solution(Result):-
one_correct_well([six,eight,two],Result),
one_correct_wrong([six,one,four],Result),
one_correct_wrong([seven,eight,zero],Result),
two_correct_wrong([two,zero,six],Result),
nothing_correct([seven,three,eight],Result).
请注意,这是一个快速尝试,因此有很多重复的代码片段,因此显然可以改进
第二个注意事项:考虑在A
中重复使用one_correct_well([A,B,C],[A,X,Y])
,而不是使用first(A, [X,Y,Z])
谓词delete/3
允许我使用从zero
到nine
的列表,不包括以下某些值:
delete([one,two,three],two,S).
-> S = [one,three].
我不是prolog的专家,所以可能有更好的方法来实现这一点,但这是我通过快速搜索找到的。
最后但并非最不重要:here是一个工作示例的SWISH链接