उत्परिवर्ती पैंगोलिन


28

यह एक कोड-गोल्फ चुनौती है, जिसके तहत आपको एक ऐसे कार्यक्रम को तैयार करने की आवश्यकता होती है जो एक क्वीन या एक क्वीन की तरह काम करता है जो मशीन सीखने को समझने के लिए खुद को संशोधित करता है।

पृष्ठभूमि

एक मूल कृत्रिम बुद्धिमत्ता कार्यक्रम है जिसे 'पैंगोलिन गेम' कहा जाता है जो यहाँ वर्णित है । मूल विचार यह है कि कार्यक्रम जब पहली बार चलता है तो पूछता है:

ठीक है, कृपया कुछ सोचें

क्या यह पैंगोलिन है?

आप तब या तो जवाब दे सकते हैं:

हाँ

किस मामले में यह कहता है:

अच्छा। यह soooo आसान था।

या नहीं तो यह कहते हैं:

ओह। खैर आप तब जीतते हैं - आप क्या सोच रहे थे?

जिस पर आप कह सकते हैं:

एक कुत्ता

जिसको यह कहेंगे

कृपया मुझे एक कुत्ते के बारे में एक प्रश्न दें, इसलिए मैं एक कुत्ते और एक पैंगोलिन के बीच का अंतर बता सकता हूं

आप जवाब दे सकते हैं

क्या यह चींटियों को खाता है?

यह तो पूछना होगा:

कुत्ते के लिए क्या जवाब है?

जिस पर आप कहेंगे

नहीं

और यह कहेगा

धन्यवाद

अगली बार जब यह चलता है, तो यह ऊपर दिए गए सवाल पूछेगा, और इस तरह के सवालों के एक द्विआधारी पेड़ का निर्माण करेगा।

चुनौती

पर्याप्त पृष्ठभूमि। यह चुनौती एक स्व-संशोधित पैंगोलिन कार्यक्रम लिखना है। नियम इस प्रकार हैं:

  1. कार्यक्रम आउटपुट (जैसा ऊपर वर्णित है) होना चाहिए STDERR। अंतिम प्रतिक्रिया हमेशा "अच्छी होगी। यह बहुत आसान था।" या "धन्यवाद"। इसके बाद, इसे प्रोग्राम के वर्तमान संस्करण या तो प्रोग्राम का एक नया संस्करण आउटपुट करना चाहिए, जिसमें प्रश्न शामिल होता है STDOUT। ऐसी भाषा में लिखा गया कोई उत्तर, जो लिखने STDOUTऔर STDERRया पढ़ने का समर्थन नहीं करता STDINहै, मान्य होगा।

  2. UNIX के तहत दूसरे शब्दों में आप इस तरह से कार्यक्रम को लागू कर सकते हैं:

उदाहरण:

$ mylanguage myprogram > myprogram.1
[dialog goes here]
$ mylanguage myprogram1 > myprogram.2
[dialog goes here]
  1. कार्यक्रम को बिल्कुल निर्दिष्ट संकेतों का उपयोग करना है (क्योंकि संकेतों को छोटा करने से कोई कौशल नहीं दिखता है)। संकेत इस प्रकार हैं (उद्धरण के बिना, और जहाँ% s प्रतिस्थापित है) निम्नानुसार हैं:

सूची:

"OK, please think of something"
"Is it %s?"
"Good. That was soooo easy."
"Oh. Well you win then -- What were you thinking of?"
"Please give me a question about %s, so I can tell the difference between %s and %s"
"What is the answer for %s?"
"Thanks"
  1. जब हाँ / नहीं जवाब की उम्मीद कर, अपने कार्यक्रम को स्वीकार करना चाहिए yया yes'हाँ' के लिए किसी भी मामले में, और nया noके लिए 'नहीं' किसी भी मामले में। आप गैर-अनुरूपता वाले इनपुट के साथ क्या करते हैं, यह आपके ऊपर है। उदाहरण के लिए, आप ऐसा कोई भी उत्तर लेने का निर्णय ले सकते हैं, जो 'हां' के साथ yया Yकिसी और के रूप में शुरू होता है ।

  2. आप मान सकते हैं कि आपूर्ति की गई चीजों के नाम और प्रश्न में केवल ASCII अक्षर, संख्याएं, रिक्त स्थान, हाइफ़न, प्रश्न चिह्न, अल्पविराम, पूर्ण विराम, कॉलोन और अर्धविराम शामिल हैं, अर्थात वे regex के बाद मेल खाते हैं ^[-?,.;: a-zA-Z]+$। यदि आप इससे अधिक का सामना कर सकते हैं (विशेष रूप से आपकी चुनी हुई भाषा में पात्रों को उद्धृत करते हुए) तो आपको स्मॉग का शिकार होना पड़ेगा, लेकिन किसी भी अतिरिक्त बिंदु को हासिल न करें।

  3. आपका कार्यक्रम पढ़ने या लिखने नहीं हो सकता है किसी भी फ़ाइल (छोड़कर STDIN, STDOUTऔर STDERR), या नेटवर्क से; विशेष रूप से यह न तो डिस्क से अपना कोड पढ़ सकता है और न ही लिख सकता है। इसका राज्य प्रोग्राम कोड में ही सहेजा जाना चाहिए।

  4. जब प्रोग्राम चलाया जाता है और सही ढंग से उत्तर का अनुमान लगाता है, तो उसे बिल्कुल एक क्वीन के रूप में प्रदर्शन करना चाहिए , अर्थात उसे STDOUTअपने कोड को बिल्कुल अपरिवर्तित लिखना होगा ।

  5. जब प्रोग्राम चलाया जाता है और गलत तरीके से उत्तर का अनुमान लगाता है, तो उसे प्रदान किए गए नए प्रश्न और उत्तर को अपने कोड में एनकोड करना होगा और उसे अपने कोड में लिखना होगा STDOUT, इसलिए यह अपने मूल अनुमान और प्रदान की गई नई वस्तु के बीच अंतर करने में सक्षम है, पहले दी गई सभी वस्तुओं के बीच अंतर करने के अलावा।

  6. आपको सॉफ़्टवेयर के कई अनुक्रमिक रन का सामना करने में सक्षम होना चाहिए ताकि यह कई वस्तुओं के बारे में सीख सके। कई रन के उदाहरण के लिए यहां देखें ।

  7. परीक्षण रन सिर में लिंक पर दिए गए हैं (जाहिर है कि केवल STDINऔर STDERRसंवाद को कवर करते हुए )।

  8. मानक खामियों को बाहर रखा गया है।


क्या कार्यक्रम को कई बार म्यूट करने और 2 से अधिक जानवरों का समर्थन करने में सक्षम होना चाहिए? यदि हां, तो क्या आप एक उदाहरण प्रदान कर सकते हैं "कृपया मुझे इसके बारे में एक प्रश्न दें ..." संवाद जब पहले से ही दो या दो से अधिक जानवरों के बारे में कार्यक्रम होता है?
क्रिस्टियन लुपस्कू

क्या होगा यदि उपयोगकर्ता "कुत्ता" के बजाय केवल "कुत्ता" कहता है? क्या हम "a / a" का पता लगाने के लिए वाक्य को पार्स करेंगे या क्या हम उत्तर का शाब्दिक उपचार कर सकते हैं? मैं मानता हूं कि आपके द्वारा दिए गए संकेत (% s) दिए गए हैं।
coredump

1
@coredump यदि उपयोगकर्ता "डॉग" को "डॉग" नहीं कहता है, तो उत्तर व्याकरणिक नहीं होगा। यह कोई मुद्दा नहीं है।
अब्लीग

1
ऊफ। रूनिक में ऐसा करने की कोशिश एक बुरा सपना होगा। प्राथमिक कारण यह है कि सभी बिट्स को मनमाने ढंग से इनपुट स्ट्रिंग्स के साथ सामना करने के लिए वायरिंग किया जाता है (जिसके परिणामस्वरूप परिणामी कार्यक्रम में स्ट्रिंग शाब्दिक के रूप में उपस्थित होने की आवश्यकता होती है) मूल रूप से असंभव होगा। ओह और रूनिक STDERR को आउटपुट नहीं दे सकते।
ड्रेको

1
यह एक मजेदार "गेम" जैसा लग रहा था, इसलिए इसे गोल्फ के बजाय, मैंने एक कोडपेन बनाया, जहां आप अपने दिल की सामग्री के लिए पैंगोलिन गेम खेल सकते हैं। का आनंद लें!
स्कंददेव

जवाबों:


20

आम लिस्प, 631 576

(let((X"a pangolin"))#1=(labels((U(M &AUX(S *QUERY-IO*))(IF(STRINGP M)(IF(Y-OR-N-P"Is it ~A?"M)(PROG1 M(FORMAT S"Good. That was soooo easy.~%"))(LET*((N(PROGN(FORMAT S"Oh. Well you win then -- What were you thinking of?~%")#2=(READ-LINE S)))(Q(PROGN(FORMAT S"Please give me a question about ~A, so I can tell the difference between ~A and ~A~%"N N M)#2#)))(PROG1(IF(Y-OR-N-P"What is the answer for ~A?"N)`(,Q ,N ,M)`(,Q ,M ,N))(FORMAT S"Thanks~%"))))(DESTRUCTURING-BIND(Q Y N)M(IF(Y-OR-N-P Q)`(,Q ,(U Y),N)`(,Q ,Y,(U N)))))))(write(list'let(list`(X',(U x)))'#1#):circle t)()))

उदाहरण सत्र

स्क्रिप्ट को नाम दें pango1.lispऔर निम्नानुसार निष्पादित करें (SBCL का उपयोग करके):

~$ sbcl --noinform --quit --load pango1.lisp > pango2.lisp
Is it a pangolin? (y or n) n
Oh. Well you win then -- What were you thinking of?
a cat
Please give me a question about a cat, so I can tell the difference between a cat and a pangolin
Does it sleep a lot?
What is the answer for a cat? (y or n) y
Thanks

एक और दौर, भालू को जोड़ना:

~$ sbcl --noinform --quit --load pango2.lisp > pango3.lisp
Does it sleep a lot? (y or n) y

Is it a cat? (y or n) n
Oh. Well you win then -- What were you thinking of?
a bear
Please give me a question about a bear, so I can tell the difference between a bear and a cat
Does it hibernate?
What is the answer for a bear? (y or n) y
Thanks

सुस्ती जोड़ना (हम उस मामले का परीक्षण करते हैं जहां उत्तर "नहीं" है):

~$ sbcl --noinform --quit --load pango3.lisp > pango4.lisp
Does it sleep a lot? (y or n) y

Does it hibernate? (y or n) n

Is it a cat? (y or n) n
Oh. Well you win then -- What were you thinking of?
a sloth
Please give me a question about a sloth, so I can tell the difference between a sloth and a cat
Does it move fast?
What is the answer for a sloth? (y or n) n
Thanks

अंतिम फ़ाइल का परीक्षण:

~$ sbcl --noinform --quit --load pango4.lisp > pango5.lisp
Does it sleep a lot? (y or n) y

Does it hibernate? (y or n) n

Does it move fast? (y or n) y

Is it a cat? (y or n) y
Good. That was soooo easy.

टिप्पणियों

  • मैं पहली बार प्रिंटिंग भूल गया "Thanks", यहाँ यह है।
  • जैसा कि आप देख सकते हैं, प्रश्नों का अनुसरण किया जाता है (y or n), जिसका कारण यह है कि मौजूदा y-or-n-pफ़ंक्शन का उपयोग करके आईओएसएम । जरूरत पड़ने पर मैं इस आउटपुट को हटाने के लिए उत्तर को अपडेट कर सकता हूं।
  • आम लिस्प में एक द्विदिश *QUERY-IO*धारा है जो उपयोगकर्ता-सहभागिता के लिए समर्पित है, जो कि यहाँ उपयोग कर रहा है। मानक आउटपुट और उपयोगकर्ता-सहभागिता गड़बड़ नहीं करते हैं, जो प्रश्न की भावना को IMHO का अनुसरण करता है।
  • प्रयोग SAVE-LISP-AND-DIEकरना अभ्यास में एक बेहतर दृष्टिकोण होगा।

उत्पन्न उत्पादन

यहाँ अंतिम उत्पन्न स्क्रिप्ट है:

(LET ((X
       '("Does it sleep a lot?"
              ("Does it hibernate?" "a bear"
               ("Does it move fast?" "a cat" "a sloth"))
              "a pangolin")))
  #1=(LABELS ((U (M &AUX (S *QUERY-IO*))
                (IF (STRINGP M)
                    (IF (Y-OR-N-P "Is it ~A?" M)
                        (PROG1 M (FORMAT S "Good. That was soooo easy.~%"))
                        (LET* ((N
                                (PROGN
                                 (FORMAT S
                                         "Oh. Well you win then -- What were you thinking of?~%")
                                 #2=(READ-LINE S)))
                               (Q
                                (PROGN
                                 (FORMAT S
                                         "Please give me a question about ~A, so I can tell the difference between ~A and ~A~%" 
                                         N N M)
                                 #2#)))
                          (PROG1
                              (IF (Y-OR-N-P "What is the answer for ~A?" N)
                                  `(,Q ,N ,M)
                                  `(,Q ,M ,N))
                            (FORMAT S "Thanks~%"))))
                    (DESTRUCTURING-BIND
                        (Q Y N)
                        M
                      (IF (Y-OR-N-P Q)
                          `(,Q ,(U Y) ,N)
                          `(,Q ,Y ,(U N)))))))
       (WRITE (LIST 'LET (LIST `(X ',(U X))) '#1#) :CIRCLE T)
       NIL))

स्पष्टीकरण

एक निर्णय वृक्ष हो सकता है:

  • एक स्ट्रिंग, जैसे "a pangolin", जो एक पत्ती का प्रतिनिधित्व करता है।
  • तीन तत्वों की सूची: (question if-true if-false)जहां questionएक बंद है हां / नहीं सवाल है, एक स्ट्रिंग के रूप में, और if-trueऔर if-falseदो संभावित प्रश्न के साथ जुड़े subtrees हैं।

Uसमारोह चलता है और देता है एक संभवतः संशोधित पेड़। प्रत्येक प्रश्न को बारी-बारी से पूछा जाता है, जो रूट से शुरू होकर पत्ती तक पहुंचता है, जबकि उपयोगकर्ता के साथ बातचीत करता है।

  • एक मध्यवर्ती नोड के लिए दिया गया मान (Q Y N)है (Q (U Y) N)(सम्मान। (Q Y (U N))) यदि प्रश्न Qका उत्तर हां (सम्मान नहीं ) है।

  • पत्ती के लिए लौटाया गया मान या तो पत्ती ही है, यदि प्रोग्राम ने उत्तर का सही अनुमान लगाया है, या एक परिष्कृत पेड़ जहां पत्ती को एक प्रश्न और दो संभावित परिणामों द्वारा प्रतिस्थापित किया जाता है, उपयोगकर्ता से लिए गए मानों के अनुसार।

यह हिस्सा सीधा नहीं था। स्रोत कोड को प्रिंट करने के लिए, हम सेल्फ-रेफरेंशियल कोड बनाने के लिए रीडर वेरिएबल का उपयोग करते हैं।*PRINT-CIRCLE*सच करने के लिए, हम सुंदर-मुद्रण के दौरान अनंत पुनरावृत्ति से बचते हैं।चाल के WRITEसाथ प्रयोग करते समय :print-circle Tयह है कि फ़ंक्शन REPL को मान भी लौटा सकता है, इस पर निर्भर करता है कि क्या लेखन अंतिम रूप है, और इसलिए, यदि REPL परिपत्र संरचनाओं को नहीं संभालता है, जैसे कि यह मानक डिफ़ॉल्ट मान द्वारा परिभाषित किया गया है *PRINT-CIRCLE*, एक अनंत पुनरावृत्ति होगी। हमें केवल यह सुनिश्चित करने की आवश्यकता है कि परिपत्र संरचना REPL को वापस नहीं किया गया है, इसीलिए LET की अंतिम स्थिति में एक NIL है। यह दृष्टिकोण समस्या को बहुत कम करता है।


अछा लगता है! की (y or n)आवश्यकता नहीं है, लेकिन मैं इसे अनुमति देने के लिए लुभा रहा हूं क्योंकि यह एक सुधार है।
अबला

@ साभार Y / n के बारे में, यह अच्छा होगा, यह मदद करता है और IMHO यह वास्तव में # 3 के साथ विरोधाभास नहीं है जो संकेतों को छोटा करने से बचने के बारे में है।
coredump

9

पायथन 2.7.6, 820 728 बाइट्स

(विभिन्न संस्करणों पर काम कर सकते हैं लेकिन मुझे यकीन नहीं है)

def r(O,R):
 import sys,marshal as m;w=sys.stderr.write;i=sys.stdin.readline;t=O;w("OK, please think of something\n");u=[]
 def y(s):w(s);return i()[0]=='y'
 while t:
  if type(t)==str:
   if y("Is it %s?"%t):w("Good. That was soooo easy.")
   else:w("Oh. Well you win then -- What were you thinking of?");I=i().strip();w("Please give me a question about %s, so I can tell the difference between %s and %s"%(I,t,I));q=i().strip();a=y("What is the answer for %s?"%q);w("Thanks");p=[q,t];p.insert(a+1,I);z=locals();exec"O"+"".join(["[%s]"%j for j in u])+"=p"in z,z;O=z["O"]
   t=0
  else:u+=[y(t[0])+1];t=t[u[-1]]
 print"import marshal as m;c=%r;d=lambda:0;d.__code__=m.loads(c);d(%r,d)"%(m.dumps(R.__code__),O)
r('a pangolin',r)

ठीक है, यह आम लिस्प उत्तर के रूप में छोटा नहीं है, लेकिन यहां कुछ कोड है!


4

पायथन 3, 544 बाइट्स

q="""
d=['a pangolin'];i=input;p=print
p("OK, Please think of something")
while len(d)!=1:
    d=d[1+(i(d[0])[0]=="n")]
x=i("Is it "+d[0]+"?")
if x[0]=="n":
    m=i("Oh. Well you win then -- What were you thinking of?")
    n=[i("Please give me a question about "+m+", so I can tell the difference between "+d[0]+" and "+m),*[[d[0]],[m]][::(i("What is the answer for "+m+"?")[0]=="n")*2-1]]
    p("Thanks")
    q=repr(n).join(q.split(repr(d)))
else:
    p("Good. That was soooo easy.")
q='q=""'+'"'+q+'""'+'"'+chr(10)+'exec(q)'
p(q)
"""
exec(q)

इसे ऑनलाइन आज़माएं!

प्रश्नों / उत्तरों / प्रतिक्रियाओं को एक सरणी में संग्रहीत किया जाता है, जहां यदि सरणी तीन आइटम (जैसे ['Does it eat ants',['a pangolin'],['a dog']]) संग्रहीत करता है, तो यह प्रश्न का उत्तर देता है और उत्तर के आधार पर या तो दूसरे या तीसरे आइटम की सामग्री के साथ दोहराता है। जब यह केवल एक आइटम के साथ एक सरणी में जाता है, तो यह सवाल पूछता है, और चूंकि इसके पूरे स्रोत में एक कोड है, यह नई शाखा को जोड़ने के लिए सरणी में एक्सटेंशन को सम्मिलित करने के लिए स्प्लिट-ज्वाइन विधि का उपयोग करने में सक्षम है। ।

मैंने मूल रूप से इसे क्वीन की आवश्यकता को साकार नहीं करने के लिए लिखा था, इसलिए प्रश्न को पुन: प्रस्तुत करना और एक तरीका खोजना होगा जिससे मैं कोड को निष्पादित कर सकता हूं और इसे स्ट्रिंग के रूप में उपयोग कर सकता हूं, लेकिन मैं अंत में अच्छा विस्तार योग्य क्वैश्चन प्रारूप के विचार पर ठोकर खाई:

q="""
print("Some actual stuff")
q='q=""'+'"'+q+'""'+'"'+chr(10)+'exec()'
print(q)
"""
exec(q)

1

पायथन 3 , 497 बाइट्स

t=["a pangolin"];c='''p=print;i=input;a=lambda q:i(q)[0]in"Yy"
def q(t):
  if len(t)<2:
    g=t[0]
    if a(f"Is it {g}?"):p("Good. That was soooo easy.")
    else:s=i("Oh. Well you win then -- What were you thinking of?");n=i(f"Please give me a question about {s}, so I can tell the difference between {s} and {g}.");t[0]=n;t+=[[g],[s]][::1-2*a(f"What is the answer for {s}?")];p("Thanks")
  else:q(t[2-a(t[0])])
p("Ok, please think of something");q(t);p(f"t={t};c=''{c!r}'';exec(c)")''';exec(c)

पेड़ के प्रतिनिधित्व के लिए हार्मलेस के जवाब के समान। यह सूची में गहराई से जाने के दौरान, जब तक केवल एक प्रतिक्रिया नहीं होती है, तब तक यह अगला प्रश्न पूछता है।

Ungolfed संस्करण (क्विनिंग के बिना)

tree = ['a pangolin']

def ask(question):
  answer = input(question + '\n')
  if answer.lower() in ['yes', 'no']:
    return answer.lower() == 'yes'
  else:
    print('Please answer "yes" or "no".')
    return ask(question)
    
def query(tree):
  if len(tree) == 1:
    guess = tree.pop()
    if ask(f'Is it {guess}?'):
      print('Good. That was soooo easy.')
      tree.append(guess)
    else:
      thing = input('Oh. Well you win then -- What were you thinking of?\n')
      new_question = input(f'Please give me a question about {thing}, so I can tell the difference between {thing} and {guess}.\n')
      answer = ask(f'What is the answer for {thing}?')
      print('Thanks')
      tree.append(new_question)
      if answer:
        tree.append([thing])
        tree.append([guess])
      else:
        tree.append([guess])
        tree.append([thing])
  else:
    if ask(tree[0]):
      query(tree[1])
    else:
      query(tree[2])
      
while True:
  input('Ok, please think of something\n')
  query(tree)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.