शूरवीरों और शूरवीरों


12

यह

इस चुनौती में, हम " शूरवीरों और शूरवीरों " पहेली को हल करने वाले कार्यक्रमों / कार्यों को लिखेंगे ।

पृष्ठभूमि

आप खुद को एक द्वीप पर पाते हैं ... आदि ... द्वीप पर हर व्यक्ति को छोड़कर या तो आप एक शूरवीर या एक दास हैं

शूरवीर केवल सही बयान कर सकते हैं ।

गुलाम केवल गलत बयान दे सकते हैं।

मैं "बयान" को कठोरता से परिभाषित नहीं करना चाहता, लेकिन हम कहेंगे कि एक बयान कुछ भी है जो "सच" या "गलत" है। ध्यान दें कि यह विरोधाभासी वाक्यों को बाहर करता है।

इस चुनौती के प्रयोजनों के लिए, आप आइलैंडर्स के समूहों में आ रहे हैं; वे आपसे बयान करेंगे।

आपका काम यह निर्धारित करना है कि कौन नाइट है और कौन एक नॉव है।

इनपुट:

आपको (किसी भी उचित प्रारूप में) निम्नलिखित जानकारी दी जाएगी:

  • उपस्थित लोगों की सूची। उन्हें अपरकेस वर्णमाला "AZ" नाम दिया जाएगा। इसके द्वारा लगाए गए लोगों की संख्या की सीमा पार नहीं की जाएगी।

  • प्रत्येक व्यक्ति जो बयान देता है। इस बारे में महत्वपूर्ण विवरण के लिए नीचे देखें।

उत्पादन

आप तब (किसी भी उचित प्रारूप में) आउटपुट करेंगे जो प्रत्येक व्यक्ति है। उदाहरण के लिए, अगर खिलाड़ी थे A B C Dऔर Aएक शूरवीर थे, लेकिन बाकी सभी शूरवीर हैं, तो आप आउटपुट कर सकते हैं

A: 1
B: 0
C: 0
D: 0

महत्वपूर्ण विवरण:

  • अपरकेस वर्णमाला AZ AZ को संदर्भित करता है।

  • वर्ण 0(शून्य) और 1(एक) क्रमशः एक "नाइट" और एक "नाइट" का उल्लेख करते हैं। (जब तक आप निर्दिष्ट करते हैं, तब तक आप किसी भी अन्य दो गैर AZ अक्षर कर सकते हैं)

  • मौजूद प्रत्येक टापू किसी भी प्राकृतिक संख्या को बयान कर सकता है, या कुछ भी नहीं कहने का विकल्प चुन सकता है।

  • सामान्य तार्किक ऑपरेटरों को बयानों में इस्तेमाल किया जा सकता है ( IS *, AND, OR, NOT )। इसके शीर्ष पर, डी मॉर्गन के नियम और शर्तों का उपयोग किया जा सकता है। निम्नलिखित उदाहरण हैं कि उन्हें एक स्पोकन पहेली में कैसे प्रस्तुत किया जा सकता है और इसके बाद वे आपके प्रोग्राम में कैसे इनपुट कर सकते हैं।

(* एक अधिक तकनीकी नोट पर। "आईएस" ऑपरेटर वास्तव में नियंत्रण के रूप में उपयोग किया जाता है (जो कि एक तार्किक ऑपरेटर नहीं है)। जब मैं कहता हूं कि "ए एक नाइट है", मेरा वास्तव में मतलब है "ए सेट के सेट का एक सदस्य है। शूरवीर। "इस्तेमाल किया गया सच्चा ऑपरेटर '।' होगा। सरलता के लिए, हम इसके बजाय '=' का उपयोग करेंगे।)

मैं निम्नलिखित का उपयोग करता हूं (आप जो भी उपयोग कर सकते हैं, जब तक यह उचित और सुसंगत है):

  • ^ तथा
  • v या
  • = है
  • ~ नहीं
  • => का तात्पर्य
  • X:व्यक्ति X का दावा है कि ...

व्यक्ति Z निम्नलिखित में से किसी भी प्रकार के कथनों का संयोजन कर सकता है:

व्यक्ति Z का कहना है कि ...

  1. व्यक्ति A एक नाइट है।

    Z: A = 1

  2. व्यक्ति क्यू एक ज्ञात है।

    Z: Q = 0

  3. मैं एक नाइट हूं।

    Z: Z = 1

  4. पर्सन A एक नाइट है या पर्सन B एक नाइट है।

    Z: ( A = 1 ) v ( B = 1)

  5. पर्सन C एक नाइट है और मैं एक शूरवीर हूं।

    Z: ( C = 1 ) ^ ( Z = 0 )

  6. व्यक्ति आर एक नाइट नहीं है।

    Z: ~( R = 1 )

इसके शीर्ष पर, इनपुट भी मॉर्गन के नियमों का उपयोग कर सकता है

  1. यह सच नहीं है कि ए और पर्सन बी दोनों ही व्यक्ति नोज़ हैं

    Z: ~( ( A = 0 ) ^ ( B = 0 ) )

  2. यह गलत है कि व्यक्ति A या व्यक्ति B एक नाइट है

    Z: ~( ( A = 1 ) v ( B = 1) )

अंत में, सशर्त और उनकी उपेक्षा का उपयोग किया जा सकता है

  1. अगर मैं एक नाइट हूं, तो व्यक्ति बी एक ज्ञात व्यक्ति है

    Z: ( Z = 1 ) => ( B = 0 )

  2. यह सच नहीं है कि यदि व्यक्ति बी एक नाइट है, तो व्यक्ति सी एक ज्ञात व्यक्ति है।

    Z: ~( ( B = 1 ) => ( C = 0 ) )

सशर्त पर नोट्स

अधिक जानकारी के लिए विकिपीडिया देखें ।

एक सशर्त कथन p => q का रूप लेता है , जहाँ p और q स्वयं कथन होते हैं। p "पूर्ववत्" है और q "परिणामी" है। यहाँ कुछ उपयोगी जानकारी है

  • किसी स्थिति का निषेध इस तरह दिखता है: ~ (p => q) p ^ ~ q के बराबर है

  • झूठे आधार का मतलब कुछ भी होता है। वह है: यदि p गलत है, तो कोई भी कथन p => q सत्य है, चाहे कोई भी क्यू हो। उदाहरण के लिए: "यदि 2 + 2 = 5 तो मैं स्पाइडरमैन हूं" एक सच्चा कथन है।

कुछ सरल परीक्षण के मामले

ये मामले निम्नलिखित फैशन में दिए गए हैं (1) हम भाषण में समस्या को कैसे हल करेंगे (2) हम इसे कंप्यूटर पर कैसे कर सकते हैं (3) सही आउटपुट जो कंप्यूटर दे सकता है।

  1. व्यक्ति ए और व्यक्ति बी आपको सड़क पर आते हैं और निम्नलिखित बयान देते हैं:

    A: B एक शूरवीर है या मैं शूरवीर हूं।

    B: A एक नाइट है।

उत्तर:

B एक नाइट है और A एक नाइट है।

इनपुट:

A B        # Cast of Characters
A: ( B = 0 ) v ( A = 1)
B: A = 1

आउटपुट:


    A = 1
    B = 1
    

  1. व्यक्ति A, B और F सड़क पर आपसे संपर्क करते हैं और निम्नलिखित बयान देते हैं:

    A: अगर मैं एक नाइट हूं, तो B एक नॉव है।

    B: यदि यह सच है, तो F एक ज्ञात है।

उत्तर:

A एक नाइट है, B एक नाइट है, F एक नाइट है।

इनपुट

A B F
A: ( A = 1 ) => ( B = 0 )
B: ( A = 1 ) => ( F = 0 ) 

आउटपुट:


    A = 1
    B = 0
    F = 1
    

  1. Q, X और W सड़क पर आपसे संपर्क करते हैं और निम्नलिखित बयान देते हैं:

    डब्ल्यू: यह सच नहीं है कि क्यू और एक्स दोनों शूरवीर हैं।

    प्रश्न: यह सच है।

    X: यदि W जो कहता है वह सत्य है, तो Q जो कहता है वह असत्य है।

उत्तर:

W और Q शूरवीर हैं। X एक ज्ञाता है।

इनपुट

Q X W
W: ~( ( Q = 1 ) ^ ( X = 1 ) )
Q: W = 1
X: ( W = 1 ) => ( Q = 0 )

उत्पादन


    W = 1
    Q = 1
    X = 0
    

वहाँ एक है इसी तरह की चुनौती 3 साल पहले पार्स करने और सशर्त शामिल नहीं है या डी मॉर्गन के पर कि केंद्रित से। और इसलिए, मैं तर्क दूंगा कि यह डूप होने से बचने के लिए ध्यान और कार्यान्वयन में पर्याप्त है।

इस चुनौती को संक्षिप्त रूप से एक ठग के रूप में बंद कर दिया गया था। इसके बाद से इसे फिर से खोल दिया गया।

मेरा दावा है कि यह चुनौती, पहले बंद, फ़ोकस में अलग है। दूसरी चुनौती अंग्रेजी पार्सिंग पर केंद्रित है, यह नहीं है। दूसरा यह केवल AND और OR का उपयोग करता है जबकि यह सशर्त का उपयोग करता है और कई और पहेलियों को हल करने की अनुमति देता है। दिन के अंत में, सवाल यह है कि उस चुनौती से उत्तर दिया जा सकता है या नहीं, लेकिन इस शर्त को अनिवार्य रूप से प्रतिस्थापित किया जा सकता है, और मेरा मानना ​​है कि सशर्त और सशर्त नकारात्मकता को शामिल करने से पर्याप्त जटिलता जुड़ जाती है, और अधिक मजबूत परिवर्तन करने की आवश्यकता होती है। इस चुनौती को पूरा करने के लिए।


अगर एक नौसैनिक कहता है तो हम क्या निष्कर्ष निकाल सकते हैं (B=1)=>(C=0)? ~((B=1)=>(C=0))या (B=1)=>(C=1)कुछ और?
njpipeorgan

5 मिनट से कम समय में ऐसा करना असंभव है। इस समस्या को SAT के रूप में जाना जाता है, और जटिलता में घातीय है। इस प्रकार सामान्य मामले में n = 26 के लिए (2 सैट नहीं), कंप्यूटर पर उचित समय में हल करना असंभव है।
लाबो

आपके पहले परीक्षण के मामले में 2 संभावित आउटपुट हैं। जैसा कि आप तार्किक उपयोग कर रहे हैं OR, यह हो सकता है A:1 B:1या A:1 B:0क्योंकि बी B=1झूठी हो सकता है जबकि ए अभी भी सच होगा।
काटेंको

@njpipeorgan यदि Knave B है, तो वह ऐसा नहीं कह सकता। एक झूठा आधार कुछ भी बताता है और इसलिए यह कथन सत्य होगा। अगर एक अलग चरित्र क्या पता है, तो आप नकार लेंगे, जो (B=1)^(C=1)कि सामान्य रूप से किस तरह से सशर्त रूप से निपटा जाता है
लियाम

1
आश्चर्य करने वालों के लिए, असली मुद्दा यह था क्योंकि मैं इनपुट क्वेरी को देख रहा था और वह शब्द पहेली को देख रहा था। यह तय किया गया है
कैमरून Aavik

जवाबों:


6

पायथन 3, 450 342 307 बाइट्स

संपादित करें: यह पता चला है कि मैं एक आयात भूल गया ...

मेरा पहला समाधान प्रश्नों के लिए लचीला नामकरण होने का लाभ लेता है

from functools import*
def g(c,r):c=c.split();l,y=len(c),range;d=[dict((c[i],n>>i&1)for i in y(l))for n in y(2**l)];return[n[1]for n in[[eval(reduce(lambda x,y:x.replace(y,str(d[i][y])),d[i],')and '.join(['not',''][d[i][s[0]]]+'('+s[2:].replace('->','<1or')for s in r)+')')),d[i]]for i in y(len(d))]if n[0]]

आप ऊपर वाले के साथ कॉल कर सकते हैं

g('Q X W', ['W: not( ( Q == 1 ) and ( X == 1 ) )','Q: W == 1', 'X: ( W == 1 ) -> ( Q == 0 )'])

यहां अगला ओपी में देखा गया प्रश्नों का एक ही प्रारूप का उपयोग करता है, इसमें कुछ संशोधन भी नहीं हैं जो मैंने पहले किए थे। यह 417 बाइट्स है क्योंकि यह दो प्रारूपों के बीच परिवर्तित होता है।

from functools import*
def g(c,r):c=c.split();l,y=len(c),range;d=[{**dict((c[i],n>>i&1)for i in y(l)),**{'v':'or','^':'and','=':'==','~':'not'}}for n in y(2**l)];f=lambda r,c:reduce(lambda x,y:x.replace(y,str(c[y])),c,('(0<1'+''.join([')^ '+['~',''][c[t[0]]]+'('+t[1]for t in[s.split(":")for s in r]])+')').replace('=>','<1or'));return[dict((o,j) for o,j in n[0].items() if o in c) for n in[[d[i],eval(f(r,d[i]))]for i in y(len(d))]if n[1]]

और यह कहा जा सकता है:

g('Q X W', ['W: ~( ( Q = 1 ) ^ ( X = 1 ) )','Q: W = 1', 'X: ( W = 1 ) => ( Q = 0 )'])

वे दोनों लौट आए

[{'X': 0, 'W': 1, 'Q': 1}]

असंगठित व्याख्या:

from functools import *
def knight_and_knaves(cast,rules):
    # turns 'A B C' into ['A','B','C']
    cast = cast.split()
    # gets all numbers that can fit in len(cast) bits
    bitmasks = range(2 ** len(cast))
    # for every bitmask, apply the value for a bit to the boolean value for each cast member.
    # This returns a dictionary of all possible outcomes.
    d=[dict((cast[i], n>>i & 1) for i in range(len(cast))) for n in bitmasks]
    # Split rules at colon
    rules = [s.split(":")for s in rules]
    # Turns list of rules into one python expression, joins each rule with ')and ', maybe a 'not' depending on if the hypothesis has the rule as a lie, and '('.
    # Also replaces '->' with '<1or' which is equivalent to it. Also starts with '(True' and ends with ')' to resolve missing parentheses
    transform_rules = lambda d, rules: ('(True' + ''.join([')and ' + ['not', ''][d[rule[0]]] + '(' + rule[1].replace('->','<1or') for rule in rules]) + ')')
    # Applys transform_rules on each outcome and evaluates the result, storing it into a list of lists where each element is [outcome, value]
    outcomes=[[d[i],eval(reduce(lambda x,y:x.replace(y,str(d[i][y])),d[i],transform_rules(d[i], rules)))] for i in range(len(d))]
    # Filters outcomes if value is True
    return[n[0]for n in outcomes if n[1]]

पीईपी 448 के उपयोग के कारण दूसरे समाधान की 3.5 (3.4 नहीं) की आवश्यकता है


1

मैथेमेटिका, 80 बाइट्स

F[c_,s_]:=Select[Thread[c->#]&/@{True,False}~Tuples~Length@c,And@@Equal@@@s/.#&]

व्याख्या

फ़ंक्शन Fदो तर्क लेता है,

  • c सभी पात्रों के नामों की एक सूची है,
  • s बयानों की एक सूची है, जिनमें से प्रत्येक में दो भाग हैं - कौन क्या कहता है।

उदाहरण के लिए, तीन वर्ण हैं, Q, X और W।

characters={q,x,w};

और वे कहते हैं,

statements=
   {{w, !((q==True)&&(x==True))   },
    {q, w==True                   },
    {x, Implies[w==True,q==False] }};

जहां Trueऔर Falseक्रमशः शूरवीरों और शूरवीरों का मतलब है। फिर

F[characters, statements]

दे देंगे {{q->True, x->False, w->True}}, जिसका अर्थ है कि केवल एक ही समाधान है कि क्यू और डब्ल्यू शूरवीर हैं जबकि एक्स एक शूरवीर है। यदि एक से अधिक समाधान हैं, तो आउटपुट जैसा दिखेगा{{...},{...},...}


एल्गोरिथ्म बहुत सरल है। {True,False}~Tuples~Length@cपात्रों के बीच शूरवीरों और शूरवीरों के सभी संभव संयोजन देता है। फिर Thread[c->#]&/@इन संयोजनों के आधार पर नियमों की एक सरणी का निर्माण करें। दो वर्ण ए और बी के मामले में, सरणी होगी

{{a->True, b->True },
 {a->True, b->False},
 {a->False,b->True },
 {a->False,b->False}}

इन नियमों की एक पंक्ति के साथ बयानों को प्रतिस्थापित करते हुए, हम एक सरणी जैसा दिखेंगे

{{True,True},{True,False},{False,False}}

इस सरणी का पहला कॉलम वक्ताओं की पहचान है, और दूसरा कॉलम इंगित करता है कि उनके कथन सही हैं या गलत। एक वैध समाधान के लिए वक्ताओं की पहचान और उनके बयानों के बीच के अनुसार की आवश्यकता होती है। ऊपर दिए गए सरणी का मतलब है कि यह संयोजन एक समाधान नहीं है, क्योंकि दूसरा स्पीकर, एक नाइट, एक गलत बयान देता है।

Select[...,And@@Equal@@@s/.#&]

प्रतिस्थापन करता है और उन संयोजनों का चयन करता है जो स्थिति को संतुष्ट करते हैं।


1

रूबी, 128

यह सभी के रूप में एक ही एल्गोरिदम है, शूरवीरों और शूरवीरों के सभी संभव संयोजनों का प्रयास करें और देखें कि कौन सी लाठी है। मेरे पास एक और है जो मैं काम कर रहा हूं, लेकिन मुझे लगता है कि यह अधिक लंबा (हालांकि अधिक दिलचस्प) होगा।

विवरण इनपुट होना चाहिए:

  • & तथा
  • | या
  • == है
  • ! नहीं
  • > का तात्पर्य
  • X: व्यक्ति X का दावा है कि ...

मुझे कोष्ठक में होने के लिए प्रत्येक कथन और उप-कथन की भी आवश्यकता है। इस संस्करण के साथ एकमात्र समस्या यह है कि यह अधिकतम 2 ^ 26 पुनरावृत्तियों से गुजरता है, और यदि वे सभी शूरवीर नहीं हैं, तो कम से कम 2 ^ (26-n) पुनरावृत्तियों ! उस परिप्रेक्ष्य में, इसका मतलब है कि अगर दो लोग हैं, और कम से कम एक गुलाम नहीं है, तो यह न्यूनतम 16,777,216 पुनरावृत्तियों को ले जाएगा !

इसे सीमित करने के लिए, मैं 168 बाइट पर निम्नलिखित जमा करता हूं। में उप 26के लिए #{o.size}161 करने के लिए इसे वापस कटौती करने के लिए।

->s{o=s[/.*?$/].split
i=0
eval h=o.zip(("%0#{o.size}b"%i+=1).chars).map{|k|k*?=}*?;until h&&o.all?{|t|!s[/#{t}:(.*)$/]||eval("(#{t}<1)^(#{$1.gsub(?>,'!=true||')})")}
h}

लेकिन अगर मैं इसके बजाय लोगों के एक सरणी और बयानों के नक्शे का उपयोग कर सकता हूं जैसे:

c[[?A, ?B],
  {
    ?A=> "( B == 0 ) | ( A == 1)",
    ?B=> "A == 1"
  }
 ]

फिर मैं इसे 128 तक ले जाता हूं।

->o,s{i=0
eval h=o.zip(("%026b"%i+=1).chars).map{|k|k*?=}*?;until h&&s.all?{|t,k|eval("(#{t}<1)^(#{k.gsub(?>,'!=true||')})")}
h}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.