कोड गोल्फ: अंग्रेजी को पार्स करके शूरवीरों और शूरवीरों की समस्या का समाधान करें


16

पृष्ठभूमि

दो लोग हैं, बिल और जॉन। उनमें से एक शूरवीर है, जो हमेशा सच कहता है, और दूसरा एक शूरवीर है, जो हमेशा झूठ कहता है। आप नहीं जानते कि कौन शूरवीर है और कौन शूरवीर है। प्रत्येक व्यक्ति तब कई कथन कहता है कि कौन शूरवीर है और कौन शूरवीर है। इस जानकारी का उपयोग करते हुए, आपको एक निष्कर्ष पर आना चाहिए कि कौन शूरवीर है और कौन शूरवीर है।

शूरवीरों और knaves तर्क समस्या Booleen बीजगणित पर आधारित है। एक व्यक्ति जो शब्द कहता है, वह बोलेन संतोषजनक संतुष्टि समस्या का कारण बनता है। घुटने के बयान हमेशा झूठे होने चाहिए और दूसरे के बयान हमेशा सही होने चाहिए।

जॉन कहते हैं "दोनों मैं एक गुलाम हूँ और बिल एक दास है"। यदि जॉन शूरवीर थे, तो यह कथन गलत होगा, इसलिए वह शूरवीर नहीं हो सकते। यदि वह शूरवीर थे और विधेयक शूरवीर थे, तब भी यह कथन असत्य होगा, यहां तक ​​कि यह भी कि पहला भाग सत्य है। तो, जॉन गुलाम है।

चुनौती

आपकी चुनौती संभव है कि सबसे छोटा कार्यक्रम लिखा जाए जो प्रत्येक व्यक्ति द्वारा दिए गए कथनों की एक सूची लेगा और यह पता लगाएगा कि कौन शूरवीर है और कौन शूरवीर है। कवर करने के लिए बहुत सारे विवरण हैं, इसलिए यह समस्या तीन खंडों में वर्णित है।

इनपुट

इनपुट एक नई पंक्ति के बाद दो लाइनें होगी। प्रत्येक पंक्ति एक वर्ण का नाम देगी, उसके बाद एक बृहदान्त्र, उसके बाद उस व्यक्ति द्वारा कहे गए कई वाक्य होंगे। यदि एक व्यक्ति शूरवीर है, तो उसके सभी वाक्य सत्य होंगे, और सभी शूरवीरों के वाक्य झूठे होंगे। एक वाक्य के पहले अक्षर को हमेशा कैपिटल किया जाएगा, और हर वाक्य एक अवधि के साथ समाप्त होगा। यहाँ एक उदाहरण है:

Joe: Both I am a knight and neither Steve is a knave nor I am a knave.
Steve: Joe is a knave. Either Joe is a knight or I am a knight.

पदच्छेद

प्रत्येक वाक्य में कम से कम एक खंड होता है। प्रत्येक खंड में कई चीजें शामिल हैं (उम्मीद है कि आप मेरे संकेतन को समझ सकते हैं):

both [clause] and [clause]
either [clause] or [clause]
neither [clause] nor [clause]
[I am | (other person's name) is] a [knight | knave]

यह असंदिग्ध है क्योंकि यह पोलिश संकेतन के समान समझा जा सकता है। यहाँ एक वाक्य का उदाहरण दिया गया है:

Both I am a knight and neither Steve is a knave nor I am a knave.

Booleen बीजगणित में अनुवाद सीधा है। "दोनों" कथन ANDs हैं, "या तो" कथन XORs हैं, और "न तो" कथन NOR हैं।

(I am a knight) AND ((Steve is a knave) NOR (I am a knave))

उत्पादन

आउटपुट में दो लाइनें होंगी। प्रत्येक पंक्ति में एक व्यक्ति का नाम (क्रम में) होता है और फिर कहता है कि वह शूरवीर है या गुलाम। हमेशा एक शूरवीर और एक शूरवीर होगा। यहाँ उपरोक्त उदाहरण के लिए आउटपुट है:

Joe is the knave.
Steve is the knight.

यदि समस्या असाध्य है (या तो आप यह नहीं बता सकते कि कौन क्या है, या कोई समाधान नहीं है), तो आपका कार्यक्रम कुछ भी कर सकता है EXCEPT एक वैध आउटपुट का उत्पादन करता है।

और ज्यादा उदाहरण

इनपुट

Sir Lancelot: Either both I am a knight and Merlin is a knave or both I am a knave and Merlin is a knight.
Merlin: Either both I am a knight and Sir Lancelot is a knight or both I am a knave and Sir Lancelot is a knave.

उत्पादन

Sir Lancelot is the knight.
Merlin is the knave.

इनपुट

David: Neither I am a knave nor Patrick is a knight. Either I am a knight or Patrick is a knave.
Patrick: Either I am a knight or both I am a knight and David is a knight.

उत्पादन

David is the knave.
Patrick is the knight.

इनपुट

Lizard: I am a knight.
Spock: I am a knave.

एक संभव उत्पादन

Rock Paper Scissors

नियम, विनियम और नोट्स

  1. मानक कोड गोल्फ नियम लागू होते हैं
  2. आपका कार्यक्रम केवल मुद्रण योग्य ASCII से बना होना चाहिए
  3. सभी इनपुट और आउटपुट STDIN और STDOUT से होंगे

केस सेंसिटिविटी के बारे में क्या? आपका वाक्यविन्यास विवरण कम है, आपके उदाहरण अपरकेस हैं। क्या असंवेदनशीलता एक आवश्यकता है?
ugoren

प्रत्येक भावना के पहले अक्षर को कैपिटल किया जाएगा, लेकिन इसके अलावा केवल नामों को कैपिटलाइज़ किया जाएगा। आप क्या विशिष्ट समस्या देख रहे हैं?
PhiNotPi

चूंकि आप उचित अंग्रेजी पूंजीकरण का उपयोग करते हैं, दोनों में पहला अक्षर / या तो / न ही संदर्भ पर निर्भर करता है। मुझे लगता है कि केस-असंवेदनशील होने का इससे निपटने का आसान तरीका है।
बदसूरत

जवाबों:


6

पायथन, 491 वर्ण

प्रत्येक पंक्ति को पायथन एक्सप्रेशन में परिवर्तित करके काम करता है, और उसे प्रकाशित करता है।
शूरवीर और शूरवीर का मूल्यांकन 0 और 1. दो लोगों के लिए किया जाता है, हम दोनों विकल्पों का प्रयास करते हैं।
उदाहरण के लिए, Joe: Steve is a knaveबन जाता है Joe==(Steve==knave)। इस तरह, यदि Joeवह एक शूरवीर है, तो परिणाम केवल सच है यदि वह झूठ बोल रहा है।
असंभव या अनिर्दिष्ट होने पर आपको बदसूरत त्रुटियां मिलती हैं। यदि असंभव है, r[0]तो एक इंडेक्स एरर है, क्योंकि rखाली है। यदि अनिर्णायक है, तो r[1:]तार की एक सूची में प्रवेश करने से परेशानी होती है।

import sys
def p():
    a=s.pop(0)
    try:return{"both":"(%s*%s)","either":"(%s|%s)","neither":"(1-(%s|%s))"}[a.lower()]%(p(),p())
    except KeyError:r=s[2];del s[:4];return"(%s==%s)"%((a,m)[a=="I"],r)
x=[];w=[]
for l in sys.stdin:
    m,l=l.split(":");w+=[m]
    for s in l.split("."):
        s=s.split()
        while s:x+=["%s==%s"%(m,p())]
k=("knave","knight")
r=[a for a in[{w[0]:z,w[1]:1-z}for z in(0,1)]if all(eval(l,{k[0]:0,k[1]:1},a)for l in x)]
print"\n".join(x+" is the "+k[r[0][x]]+"."for x in w+r[1:])

3

रूबी, 352 वर्ण

समाधान काफी लंबा हो गया इसलिए गोल्फ के लिए अभी भी कुछ जगह हो सकती है। इसे इनपुट को अच्छी तरह से बनाने की आवश्यकता है (जैसा कि ऊपर दिए गए सभी उदाहरण हैं - लेकिन किसी व्यक्ति को "दोनों" ...) का नाम देने की कोशिश न करें।

q=->{gets.split /: |\.\s/}
C,*E=q[]
D,*F=q[]
r=->c,m{t=c.shift;t[1]?(x=r[c,m];c.shift;y=r[c,m];t[0]==?B?x&y :t[0]==?E?x^y :1-(x|y)):(c.shift(2);h=c.shift[2]==?I?m : 1-m;t==?I?h :1-h)}
s=->u,v,b{u.map{|c|r[c.gsub(v,?J).upcase.split,b]==b}.all?}
t=->b{s[E,D,b]&&s[F,C,1-b]}
u=->v,b{v+" is the kn#{b ?:ight: :ave}."}
puts t[1]^t[0]&&u[C,t[1]]+$/+u[D,t[0]]

आप आउटपुट में अवधियों को छोड़ना चाहते हैं, लेकिन ऐसा लगता है कि यह दो वर्णों को ठीक करता है।
PhiNotPi 12

1
@PhiNotPi किया। क्या शून्य-चरित्र ठीक था ...
हावर्ड

0

पर्ल - 483 बाइट्स

(($a,$b),($c,$d))=map{split':'}@ARGV;$h='y';$i='x';$s=' is the kn';$g='ight.';$v='ave.';for($b,$d){$_.=' 1';s/ am a | is a /==/g;s/knight/1)/g;s/knave/0)/g;s/I=/(\$$i=/g;s/($a|$c)=/(\$$h=/g;s/([^.]+)\./($1)and/g;s/ or / xor /g;s/ nor / or /g;while(s/(?<= )(\w+ \((?:[^()]+|(?1))\) \w+ \((?:[^()]+|(?1))\))/($1)/g){}s/neither/!/gi;s/both|either//gi;$h=$i++}$x=0;$y=1;$k=!eval($b)&&eval($d);$x=$y--;$n=!eval($d)&&eval($b);print"$a$s$v
$c$s$g"if($k&&!$n);print"$a$s$g
$c$s$v"if($n&&!$k)

पायथन समाधान के समान। यह वाक्यों को पर्ल कोड में घटाता है और फिर evalउन्हें एस करता है। यदि इनपुट अजीब है, तो यह लगभग वैध आउटपुट प्रिंट कर सकता है, लेकिन यह अविश्वसनीय होने पर कुछ भी प्रिंट नहीं करता है। अच्छी तरह से गठित इनपुट उम्मीद के मुताबिक काम करता है। वाक्य कमांड लाइन पर उद्धरणों के अंदर पारित किए जाते हैं और किसी विशेष झंडे की आवश्यकता नहीं होती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.