Dies ist eine Code-Golf-Herausforderung, bei der Sie ein Programm entwickeln müssen, das sich wie ein Quine verhält oder das sich selbst modifiziert, um das maschinelle Lernen zu veranschaulichen.
Hintergrund
Es ist ein grundlegendes künstliche Intelligenz Programm ‚das pangolin Spiel‘ genannt , die beschrieben wird , hier . Die Grundidee ist, dass das Programm beim ersten Start fragt:
OK, bitte denken Sie an etwas
Ist es ein Pangolin?
Sie können dann entweder antworten:
Ja
In welchem Fall heißt es:
Gut. Das war soooo einfach.
Oder wenn nicht, heißt es:
Oh. Na dann gewinnst du - woran hast du gedacht?
Zu dem könnte man sagen:
ein Hund
Zu dem würde es sagen
Bitte geben Sie mir eine Frage zu einem Hund, damit ich den Unterschied zwischen einem Hund und einem Pangolin erkennen kann
du könntest antworten
Frisst es Ameisen?
Es würde dann fragen:
Was ist die Antwort für einen Hund?
Zu dem würdest du sagen
Nein
Und es würde sagen
Vielen Dank
Wenn es das nächste Mal ausgeführt wird, würde es die obige Frage stellen und einen binären Baum solcher Fragen aufbauen.
Die Herausforderung
Genug vom Hintergrund. Diese Herausforderung besteht darin, ein selbstmodifizierendes Pangolin-Programm zu schreiben. Die Regeln sind wie folgt:
Die Programmausgabe (wie oben beschrieben) sollte an sein
STDERR
. Die endgültige Antwort lautet immer "Gut. Das war soooo einfach." oder "Danke". Danach sollte entweder die aktuelle Version des Programms oder eine neue Version des Programms ausgegeben werden, die die Frage enthältSTDOUT
. Keine Antwort, die in einer Sprache verfasst wurde, die das SchreibenSTDOUT
undSTDERR
Lesen nicht unterstützt,STDIN
ist gültig.Mit anderen Worten, unter UNIX können Sie das Programm folgendermaßen aufrufen:
Beispiel:
$ mylanguage myprogram > myprogram.1
[dialog goes here]
$ mylanguage myprogram1 > myprogram.2
[dialog goes here]
- Das Programm muss genau die angegebenen Eingabeaufforderungen verwenden (da das Verkürzen der Eingabeaufforderungen keine Fertigkeiten zeigt). Die Eingabeaufforderungen lauten (ohne Anführungszeichen und wobei% s ersetzt wird) wie folgt:
Liste:
"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"
Wenn erwartet Ja / Nein - Antworten, soll Ihr Programm übernehmen
y
oderyes
in jedem Fall für ‚Ja‘, undn
oderno
in jedem Fall für ‚Nein‘. Was Sie mit nicht konformen Eingaben tun, liegt bei Ihnen. Zum Beispiel könnten Sie sich dafür entscheiden, eine Antwort zu nehmen, die mity
oderY
als "Ja" beginnt , und alles andere als "Nein".Sie können davon ausgehen, dass die Namen der gelieferten Dinge und der Fragen nur aus ASCII-Buchstaben, -Zahlen, -Leerzeichen, -Trennstrichen, -Fragezeichen, -Kommas, -Punkten, -Doppelpunkten und -Semikolons bestehen, dh sie stimmen mit dem folgenden regulären Ausdruck überein
^[-?,.;: a-zA-Z]+$
. Wenn Sie mehr als das bewältigen können (insbesondere die Anführungszeichen in der von Ihnen gewählten Sprache), werden Sie selbstgefällig, erhalten aber keine zusätzlichen Punkte.Ihr Programm kann eine beliebige Datei nicht lesen oder schreiben (ohne
STDIN
,STDOUT
undSTDERR
), oder aus dem Netz; Insbesondere kann er keinen eigenen Code von der Festplatte lesen oder schreiben. Sein Zustand muss im Programmcode selbst gespeichert werden.Wenn das Programm ausgeführt wird und die Antwort richtig errät, muss es genau wie ein Quine funktionieren, dh es muss
STDOUT
unverändert in genau seinen eigenen Code schreiben .Wenn das Programm ausgeführt wird und die Antwort falsch errät, muss es die bereitgestellte neue Frage und Antwort in seinem eigenen Code codieren und in seinen eigenen Code schreiben
STDOUT
, damit es in der Lage ist, zwischen seiner ursprünglichen Vermutung und dem bereitgestellten neuen Objekt zu unterscheiden Neben der Unterscheidung zwischen allen zuvor gegebenen Objekten.Sie müssen in der Lage sein, mehrere sequenzielle Läufe der Software zu bewältigen, damit sie viele Objekte erkennt. Sehen Sie hier Beispiele für mehrere Läufe.
Testläufe finden Sie am Link im Kopf (natürlich nur im
STDIN
undSTDERR
-Dialog).Standardlücken sind ausgeschlossen.
Antworten:
Gemeines Lisp,
631576Beispielsitzung
Benennen Sie das Skript
pango1.lisp
und führen Sie es wie folgt aus (mit SBCL):Eine weitere Runde mit dem Bären:
Faultier hinzufügen (wir testen den Fall, in dem die Antwort "nein" lautet):
Testen der letzten Datei:
Bemerkungen
"Thanks"
, hier ist es.(y or n)
, weil ich die vorhandeney-or-n-p
Funktion verwende. Ich kann die Antwort aktualisieren, um diese Ausgabe bei Bedarf zu entfernen.*QUERY-IO*
Stream für die Benutzerinteraktion, den ich hier verwende. Standard-Ausgabe und Benutzer-Interaktion nicht durcheinander, was IMHO den Geist der Frage folgt.SAVE-LISP-AND-DIE
wäre in der Praxis ein besserer Ansatz.Erzeugte Ausgabe
Hier ist das zuletzt generierte Skript:
Erklärungen
Ein Entscheidungsbaum kann sein:
"a pangolin"
, die ein Blatt darstellt.(question if-true if-false)
Woquestion
ist eine geschlossene Ja / Nein- Frage als Zeichenfolge undif-true
undif-false
sind die zwei möglichen Unterbäume, die mit der Frage verknüpft sind.Die
U
Funktion geht und gibt einen möglicherweise geänderten Baum zurück. Jede Frage wird der Reihe nach gestellt, angefangen von der Wurzel bis zum Erreichen eines Blattes, während mit dem Benutzer interagiert wird.Der zurückgegebene Wert für einen Zwischenknoten
(Q Y N)
ist(Q (U Y) N)
(bzw.(Q Y (U N))
), wenn die Antwort auf die Frage Ja (bzw. Nein )Q
lautet .Der zurückgegebene Wert für ein Blatt ist entweder das Blatt selbst, wenn das Programm die Antwort richtig erraten hat, oder ein verfeinerter Baum, in dem das Blatt durch eine Frage und zwei mögliche Ergebnisse gemäß den vom Benutzer übernommenen Werten ersetzt wird.
Dieser Teil war ziemlich einfach. Um den Quellcode zu drucken, verwenden wir Leservariablen, um selbstreferenziellen Code zu erstellen.
Durch SetzenDer Trick bei der Verwendung*PRINT-CIRCLE*
von "true" vermeiden wir eine unendliche Rekursion beim Pretty-Printing.WRITE
von:print-circle T
besteht darin, dass die Funktion möglicherweise auch den Wert an die REPL zurückgibt, abhängig davon, ob write die letzte Form ist. Wenn die REPL also keine kreisförmigen Strukturen verarbeitet, wie es durch den Standardwert von definiert ist*PRINT-CIRCLE*
wird es eine unendliche Rekursion geben. Wir müssen nur sicherstellen, dass die kreisförmige Struktur nicht an die REPL zurückgegeben wird, deshalb gibt es eine NIL an der letzten Position des LET. Dieser Ansatz reduziert das Problem erheblich.quelle
(y or n)
ist nicht erforderlich, aber ich bin versucht, es zuzulassen, da es eine Verbesserung ist.Python 2.7.6,
820728 Bytes(Könnte an verschiedenen Versionen arbeiten, aber ich bin mir nicht sicher)
Nun, es ist nicht so kurz wie die Common-Lisp-Antwort, aber hier ist ein Code!
quelle
Python 3, 544 Bytes
Probieren Sie es online!
Die Fragen / Antworten / Antworten werden in einem Array gespeichert. Wenn das Array drei Elemente (z. B.
['Does it eat ants',['a pangolin'],['a dog']]
) speichert , erhält es eine Antwort auf die Frage und wird je nach Antwort nur mit dem Inhalt des zweiten oder dritten Elements wiederholt. Wenn es zu einem Array mit nur einem Element kommt, stellt es die Frage, und da sein gesamter Quellcode eine Zeichenfolge enthält, kann es die Split-Join-Methode verwenden, um die Erweiterung in das Array einzufügen, um den neuen Zweig hinzuzufügen .Ursprünglich schrieb ich dies, ohne die Anforderungen an das Quine-Format zu erfüllen. Daher war es schwierig, die Frage erneut zu lesen und einen Weg zu finden, wie ich Code ausführen und als Zeichenfolge verwenden kann. Schließlich stieß ich auf die Idee des erweiterbaren Quine-Formats:
quelle
Python 3 , 497 Bytes
Ganz ähnlich wie die Antwort von Harmless für die Baumdarstellung. Die nächste Frage wird rekursiv gestellt, während die Liste vertieft wird, bis nur noch eine Antwort vorliegt.
Ungolfed version (ohne quining)
quelle