需要帮助写一个prolog声明

时间:2018-02-07 01:57:04

标签: prolog

我想写一个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).

1 个答案:

答案 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允许我使用从zeronine的列表,不包括以下某些值:

delete([one,two,three],two,S).
-> S = [one,three].

我不是prolog的专家,所以可能有更好的方法来实现这一点,但这是我通过快速搜索找到的。

最后但并非最不重要:here是一个工作示例的SWISH链接