Prolog

2009-12-21 8 views
9

का उपयोग कर एक तर्क पहेली आपराधिक ए, बी, सी और डीProlog

में से एक है सुलझाने

ए का कहना है: "यह नहीं मुझे"
बी का कहना है:
सी कहते हैं, "यह विकास है": "यह बी है"
डी कहते हैं:

"यह मैं नहीं हूं" और हम जानते हैं कि उनमें से केवल एक सच्चाई बताता है।

वह कौन है? मैं प्रोलॉग का उपयोग करके इसे हल करना चाहता हूं।

यह एक साक्षात्कार प्रश्न है।

+0

मुझे लगता है कि सही मिला: एक एक अपराधी है, लेकिन तीन झूठे हैं ?! – ThomasH

उत्तर

23

एक-लाइनर समाधान

?- 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. 
+0

+1 यह दिलचस्प है। – ThomasH

+0

क्या होगा यदि अपराधी ए, बी, सी, डी के दो हो सकते हैं? – user198729

+0

@ user198729: फिर ए + बी + सी + डी =: = 1; ए + बी + सी + डी =: = 2 के साथ खंड समाप्त करें। –

17

अस्वीकरण: यह 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 आपराधिक नहीं है, अन्यथा सत्य नहीं है। धारणा के तहत d आपराधिक है, बी सच है अन्यथा नहीं। Asf। यही है, ए, बी, चर ... एक विशिष्ट आपराधिक दिया, corrsponding व्यक्ति की सच्चाई पर कब्जा।

एक ज्ञात बाधा के रूप में यह तथ्य है कि उनमें से केवल एक सत्य है, उनके सत्य मूल्यों का योग होना चाहिए 1. बैकट्रैकिंग पर, प्रोलॉग के लिए अगली बाध्यकारी बनाता है, और फिर से इसके माध्यम से चलता है। बाधा बाहर निकलती है केवल a आपराधिक है (और d सत्य बता रहा है, अगर मुझे गलत नहीं है)। प्यारा।

8

यहां एक और समाधान है जो मुझे ज़ोनिक्स की तुलना में थोड़ा कम गुप्त लगता है। एसडब्ल्यूआई-प्रोलॉग में परीक्षण किया गया।

% 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. 
2

ऐसा ही एक समस्या और इसी समाधान भी यहां पाया जा सकता:

https://github.com/LogtalkDotOrg/logtalk3/blob/master/examples/puzzles/jam_thief.lgt

समाधान Kaarel द्वारा पोस्ट की तरह

, एक अनुरोध करना संभव है समाधान के लिए औचित्य/स्पष्टीकरण मिला।

+0

कृपया [केवल लिंक ही लिंक] प्रदान न करें (http://meta.stackoverflow.com/tags/link-only-answers/info), कुछ और लिखें। –

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)).