罪犯是A,B,C和D之一。
A说:“这不是我” B说:“这是D” C说:“这是B” D说:“这不是我”
我们知道其中只有一个说实话。
谁是谁?我想用Prolog来解决它。
这是一个面试问题。
答案 0 :(得分:24)
单线解决方案
?- member(K,[a,b,c,d]),(K\=a->A=1;A=0),(K=d->B=1;B=0),(K=b->C=1;C=0),(K\=d->D=1;D=0),A+B+C+D=:=1.
K = a,
A = 0,
B = 0,
C = 0,
D = 1 ;
false.
答案 1 :(得分:20)
免责声明:这是 Xonix '解决方案。如果你愿意,可以投票他。但是,由于我要弄清楚发生了什么事,我想我也可以提出我的意见,以便其他人可以受益。
首先,这是他作为正确条款的解决方案:
criminal(K):-
member(K,[a,b,c,d]),
(K\=a -> A=1;A=0),
(K=d -> B=1;B=0),
(K=b -> C=1;C=0),
(K\=d -> D=1;D=0),
A+B+C+D=:=1.
它是这样的:
首先,他会查看个人名单(必须是小写,所以他们不是变量)。 K
依次为每个人实例化。{/ p>
每个可能的K
值都会贯穿其余的条款。 K
可以被解释为罪犯的假设。接下来的4行是为每个变量A,B,C和D提供绑定。你可以这样读:它们假设a
不是罪犯,a是真实的,否则不是。假设d
是罪犯,b是真实的,否则不是。 ASF。也就是说,变量A,B,......在特定罪犯的情况下捕获了相应个体的真实性。
一个已知的约束是这样一个事实,即只有其中一个是真实的,它们的真值的总和必须是1.在回溯时,Prolog为K做下一个绑定,并再次运行它。事实证明只有在a
是罪犯的情况下才能满足约束(而d
说实话,如果我没有弄错的话)。可爱。
答案 2 :(得分:8)
这是另一种解决方案,我发现它比Xonix的神秘程度要低一些。 在SWI-Prolog中测试。
% To find a criminal and the truthteller
% 1. Pick a possible criminal
% 2. Pick a possible truthteller and the remaining liars
% 3. Assert that the truthteller's statement is the truth
% 4. Assert that every liar's statement is not the truth
% If both the assertions succeed
% then we have found a criminal and the truthteller.
criminal_and_truthteller(Criminal, Truthteller) :-
Group = [a, b, c, d],
member(Criminal, Group),
select(Truthteller, Group, Liars),
statement(Truthteller, Criminal, Truth),
Truth,
forall(
member(Liar, Liars),
(statement(Liar, Criminal, Lie), \+ Lie)
).
% Statements
% Arg 1: Who says
% Arg 2: About whom
% Arg 3: Which statement
% e.g. "a claims that a is not a criminal"
statement(a, C, a \= C).
statement(b, C, d = C).
statement(c, C, b = C).
statement(d, C, d \= C).
用法示例:
?- criminal_and_truthteller(Criminal, Truthteller).
Criminal = a,
Truthteller = d ;
false.
答案 3 :(得分:3)
我遇到了这个问题,想要试一试:
a(K) :- K \== a.
b(d).
c(b).
d(K) :- K \== d.
solve(TruthTeller) :-
member(K, [a, b, c, d]),
xor([a(K), b(K), c(K), d(K)], Truth),
Truth =.. [TruthTeller|_].
xor([Head|Tail], Result) :-
( call(Head)
-> forall(member(X, Tail), \+ call(X)), Result = Head
; xor(Tail, Result)).
答案 4 :(得分:2)
此处也可以找到类似的问题和相应的解决方案:
https://github.com/LogtalkDotOrg/logtalk3/blob/master/examples/puzzles/jam_thief.lgt
与Kaarel发布的解决方案一样,可以请求找到解决方案的理由/解释。