逻辑谜题的罪犯是A,B,C和D.解决在使用的Prolog
之一一说: “这不是我”
乙说: “这是d”
Ç说: “这是B”
d说:“这不是我”
而且我们知道,只有其中一人道出了实情。
谁是谁?我想通过使用Prolog解决它。
这是一个面试问题。
逻辑谜题的罪犯是A,B,C和D.解决在使用的Prolog
之一一说: “这不是我”
乙说: “这是d”
Ç说: “这是B”
d说:“这不是我”
而且我们知道,只有其中一人道出了实情。
谁是谁?我想通过使用Prolog解决它。
这是一个面试问题。
一衬垫溶液
?- 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这很有趣。 – ThomasH 2009-12-21 22:15:13
如果犯罪分子可以是a,b,c,d中的两个,该怎么办? – user198729 2009-12-23 03:33:54
@ user198729:然后以A + B + C + D =:= 1; A + B + C + D =:= 2结束子句。 – 2010-06-20 11:27:14
声明:这是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
被依次实例化给它们中的每一个。
对于K
的每个可能的值,他会贯穿条款的其余部分。 K
可以解释为罪犯是谁的假设。接下来的4行是为每个变量A,B,C和D提供绑定。你可以像这样读取它们:假设a
不是罪犯,否则a是真实的。假设d
是罪犯,否则b是真实的。 ASF。也就是说,变量A,B ......捕捉到了相应犯罪人的真实性。
由于已知的约束条件是只有其中一个是真实的,所以它们的真值总和必须为1.在回溯时,Prolog为K下一个绑定,并再次运行。原来,只有当a
是犯罪分子才能满足约束条件(而d
说的是实话,如果我没弄错的话)。可爱。
这是另一种解决方案,我发现它比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.
类似的问题和相应的解决方案也可以在这里找到:
https://github.com/LogtalkDotOrg/logtalk3/blob/master/examples/puzzles/jam_thief.lgt
喜欢张贴由Kaarel该溶液中,可以请求一个找到解决方案的理由/解释。
请不要提供[只链接的答案](http://meta.stackoverflow.com/tags/link-only-answers/info),写更多。 – 2013-05-05 09:50:24
我跑过这个问题,想给它一个镜头:
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)).
难道我得到这个权利:一个是犯罪,但三是骗子? – ThomasH 2009-12-21 12:44:31