Die Herausforderung
In dieser Herausforderung geben Sie eine Quellsprache S
und eine Zielsprache an T
. Ihre Aufgabe ist es, das folgende Programm P
in der Sprache zu schreiben S
. Wenn ein gültiges Programm Q
in der Sprache T
als Eingabe für angegeben wird P
, wird ein gültiges Programm R
in der Sprache ausgegeben, T
das keine Ein- und Ausgaben vornimmt Q(R)
, dh das Programm, Q
das auf den Quellcode von angewendet wird R
. Außerdem sollten Sie in Ihrer Antwort ein nicht triviales Beispielprogramm Q
(je interessanter, desto besser, obwohl Sie dafür keine Punkte erzielen), das resultierende Programm R
und die Ausgabe von präsentieren R
. Dies ist Code-Golf, also der kürzeste Code für P
Gewinne.
Mit anderen Worten, dies ist eine Herausforderung beim Schreiben eines "universellen Quine-Konstruktors", mit dem beliebige Arten von verallgemeinerten Quines erstellt werden können.
Klarstellungen
- Ihre Ausgangs- und Zielsprache sind möglicherweise identisch.
- Das Programm
P
sollte eine Zeichenfolge als Eingabe (von STDIN oder gleichwertig) und eine Zeichenfolge (an STDOUT oder gleichwertig) ausgeben, wie jedes AusgabeprogrammR
. - Die Eingabeprogramme
Q
sollten auch eine Zeichenfolge in eine andere Zeichenfolge umwandeln, ihre Form ist jedoch flexibler: Dies können Zeichenfolge-zu-Zeichenfolge-Funktionen, Codeausschnitte sein, die eine Variable mit einem bestimmten Namen ändern, und Ausschnitte, die den Datenstapel ändern, wenn Ihre Zielsprache Sie können die Form derQ
's auch weiter einschränken , indem Sie angeben, dass sie beispielsweise keine Kommentare enthalten dürfen. Sie müssen jedoch in der Lage sein, jede berechenbare Zeichenfolge-zu-Zeichenfolge-Funktion als Eingabeprogramm zu implementierenQ
, und Sie müssen explizit angeben, wie sie funktionieren und welche weiteren Einschränkungen Sie ihnen auferlegen. - Das Ausgabeprogramm
R
sollte eigentlich eine (verallgemeinerte) Quine sein, daher darf es keine Eingaben (Benutzereingaben, Dateien usw.) lesen, sofernQ
dies nicht der Fall ist. - Standardlücken sind nicht zulässig.
Ein Beispiel
Angenommen, ich wähle Python als Ausgangssprache und Haskell als Zielsprache und fordere außerdem, dass das Eingabeprogramm eine einzeilige Definition einer String -> String
Funktion mit dem Namen ist f
. Wenn ich das Saitenumkehrprogramm gebe
f x = reverse x
Als Eingabe für mein Python-Programm P
wird der Quellcode eines anderen Haskell-Programms ausgegeben R
. Dieses Programm druckt den Quellcode von auf STDOUT R
, jedoch in umgekehrter Reihenfolge . If P
erhält die Identitätsfunktion
f x = x
als Eingabe ist das Ausgabeprogramm R
ein Quine.
quelle
Haskell-Ausdrücke → Haskell-Ausdrücke, 41 Byte
Probieren Sie es online!
Wie es funktioniert
P $ "Q"
=((++)<*>show).('(':).(++")$(++)<*>show$") $ "Q"
konstruiert"R"
von(++")$(++)<*>show$")
: Anhängen der Zeichenfolge")$(++)<*>show$"
,('(':)
: Voranstellen des Zeichens'('
und(++)<*>show
(=\x->x++show x
): Anhängen einer zitierten Version davon,resultierend in
"R"
="(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
.R
=(Q)$(++)<*>show$"(Q)$(++)<*>show$"
arbeitet von"(Q)$(++)<*>show$"
,(++)<*>show
: Anhängen einer zitierten Version davon,Q
,resultierend in
Q "(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
=Q "R"
.(Die Parens
Q
sind notwendig, weilQ
sie$
genauso leicht enthalten können wie es derR
Fall ist und$
leider rechtsassoziativ ist.)Demo
quelle
$
muss die Klammern, sondern auch Hinterlet
,do
oder Lambda - Ausdrücke.let
/if
/case
/do
wenn ich sie selbst nicht emittieren. Vielleicht ist es auch gut, dass ich nicht musste.Quelle = Ziel = JavaScript, 66
Annahmen für Q:
Q
sollte eine anonyme Zeichenfolge-zu-Zeichenfolge-JavaScript-Funktion sein.Beispiele:
function(s) { return s.split('').reverse().join(''); }
In diesem Fall ist
P(Q)
(oderR
):function a(){console.log(function(s) { return s.split('').reverse().join(''); }(a+'a()'))}a()
und wenn wir es ausführen, erhalten wir:)(a}))')(a'+a(} ;)''(nioj.)(esrever.)''(tilps.s nruter { )s(noitcnuf(gol.elosnoc{)(a noitcnuf
das ist genau das Gleiche wieQ(R)
.function(s) { return s; }
In diesem Fall ist
P(Q)
(oderR
):function a(){console.log(function(s) { return s; }(a+'a()'))}a()
eine JavaScript-Quine . Unnötig zu sagen,Q(R)
wird das gleiche sein, da Q die Identitätsfunktion ist.Einige Notizen:
STDIN in JavaScript ist traditionell
prompt()
, ich habe mir jedoch erlaubt, von der Tradition vonalert()
STDOUT abzusehen, um die Ausführung der Ausgabe als Programm mit Copy-Paste zu vereinfachen. (Ich weiß, dass ich bis zu 12 Zeichen speichern kann , wenn ich zu änderealert()
.)Ich kann die Dinge in ES6 auch viel kürzer machen, aber ich möchte vorerst bei Native JavaScript bleiben. Ich denke darüber nach, in Zukunft eine S = Scala, T = ECMA6 Antwort einzureichen, nur für die Erfahrung.
Mir ist auch klar, dass JavaScript CJam im Code-Golf fast nie schlagen kann , aber ich musste diese Herausforderung annehmen! Es war sicher lustig.
quelle
Gelee → 7 , 9 Bytes
Probieren Sie es online!
Q ist eine 7-Funktion (dh, sie geht nicht über das oberste Stack-Element hinaus und führt die E / A über den Stack aus) und wird als Befehlszeilenargument angegeben.
Erläuterung
Das 7 Programm
Der universelle Quine-Konstruktor in 7, den ich hier verwende, ist:
Das Erste, was zu beachten ist, ist, dass die führende 7 das Äquivalent von führendem Leerzeichen ist und keine Auswirkung auf das Programm hat. Der einzige Grund, warum dies der Fall ist, besteht darin, die PPCG-Regeln gegen Quines zu befolgen (sie werden nicht von sich
1
selbst, sondern von der Sekunde im Programm codiert ).Der Rest des Programms ist ein einzelnes Stapelelement (es hat ein ausgeglichenes
7
s und6
s), das beim Ausführen Folgendes ausführt:Mit anderen Worten, dieses Stack-Element ist ein Programm, das den Anfang des Stapels mit
7
vorangestelltem Text im Ausgabeformat 7 druckt (was bedeutet, dass "wörtlich mit derselben Codierung wie der Quellcode gedruckt wird") und somit eindeutig die beste Codierung für ist Quinen). Hier ist es ein Glücksfall, dass wir das Literal7
für zwei Zwecke wiederverwenden können (das Ausgabeformat und das führende Leerzeichen.) Durch Einfügen von etwas direkt vor dem Finale3
können wir eindeutig eine Funktion7
der Eingabe ausgeben, anstatt nur die Ausgabe7
und das direkt eingeben.Wie kommt dieses Stack-Element zu seinem eigenen Quellcode? Nun, wenn das Programmende erreicht ist, ist 7
eval
standardmäßig das oberste Stack-Element. Es ist jedoch nicht tatsächlich aus dem Stapel herausgesprungen, sodass daseval
geführte Stapelelementliteral immer noch vorhanden ist. (Mit anderen Worten, das Programm liest nicht seinen eigenen Quellcode, was durch die Tatsache belegt wird, dass es nicht in der Lage ist, das7
am Programmanfang stehende Trennzeichen zu sehen , das eher ein Stapelelement als ein Teil eines Buchstabens ist - sondern es besteht hauptsächlich aus einem Literal,eval
das standardmäßig geführt wird.)Das Jelly-Programm
Dies ist vielleicht eines der am wenigsten Jelly-ähnlichen Jelly-Programme, die ich geschrieben habe. Es besteht aus drei nilads (
“ṚƓ^ṾṂ’
,³
,3
), die nur in Ausgabefolge sind , da keine Operationen an ihnen durchgeführt werden. Das3
ist offensichtlich genug, nur eine ganzzahlige Konstante zu sein. Das³
ist auch einfach, wenn Sie Jelly kennen: Es ist Jellys explizite Notation für das erste Befehlszeilenargument (wo Jelly normalerweise seine Eingabe macht). Der Rest des Jelly-Programms stellt den Großteil meines 7 Universal Quine-Konstruktors dar. Indem wir die Tatsache ausnutzen, dass alle Befehle in 7 mit ASCII-Ziffern dargestellt werden können, können wir interpretieren717162234430
nicht als Folge von Befehlen oder sogar als Oktalzahl (wie es konzeptionell ist), sondern als Dezimalzahl, was bedeutet, dass wir keine spezielle Formatierung für die Ausgabe benötigen. Diese Dezimalzahl wird“ṚƓ^ṾṂ’
in Jellys komprimierter Ganzzahlnotation.Beispiel
Wenn wir
24053
als Programm Q angeben, erhalten wir die folgende Ausgabe:Probieren Sie es online!
2405
verkettet das oberste Stapelelement mit sich selbst:(Der letzte Schritt sieht möglicherweise etwas verwirrend aus. Wenn Sie ein Stack-Element maskieren, wird jeder darin enthaltene Befehl von "Diesen Befehl ausführen" in "Diesen Befehl an den Anfang des Stapels anhängen" konvertiert, sodass jeder Befehl an das Original angehängt wird oberstes Stapelelement, während es läuft.)
Wenn Sie das resultierende Programm R ausführen, erhalten Sie zwei Kopien von R:
quelle
CJam → CJam, 13 Bytes
Probieren Sie es online!
Die Eingabe
Q
sollte ein Codeausschnitt sein, der die einzige Zeichenfolge im Stapel ändert.Q
wird von stdin gelesen.Beispiel
Eingang:
Es wird ein Leerzeichen zwischen zwei Zeichen eingefügt und die Zeichenfolge umgekehrt.
Ausgabe:
Ausgabe der verallgemeinerten Quine:
Erläuterung
Zunächst wird das Quine ausgewertet, damit wir seine Zeichenfolgendarstellung ohne unnötige doppelte Anführungszeichen erhalten. Ersetzen Sie dann die Nutzlast durch die Eingabe.
Es könnte sein,
{`"_~"+ }_~7qt
dass der Raum der Platzhalter der Nutzlast ist. Aber die Änderung der Nutzlast7
spart ein Byte.quelle
Holzkohle → Perl (5),
2933 BytesProbieren Sie es online!
Das Perl-Programm Q sollte ein Snippet zurückgeben, das die Eingabe als Zeichenfolge auf die rechte Seite nimmt und die Ausgabe in der Variablen bereitstellt
$_
. (Beliebige Perl-Funktionen können in dieses Formular konvertiert werden, indem sie wiesub x {…}; $_=x
folgt umbrochen werden . In den meisten Fällen bedeutet die Perl-Syntax jedoch, dass kein Umbruch erforderlich ist.)Erläuterung
Die Perl
So sieht der universelle Perl-Quine-Konstruktor aus:
(In den meisten Fällen würden Sie gerne Golf spielen
$_=q(say…"\$_=q($_);eval");eval
, aber ich bin mir nicht sicher, ob Sie darin beliebigen Perl-Code einfügen…
können.)Mit anderen Worten, wir haben einen äußeren Wrapper,
$_=q(…);eval
der eine Zeichenfolge zuweist$_
und dann auswertet. Innerhalb des Wrappers befindet"\$_=q($_);eval"
sich also eine Rekonstruktion des Wrappers zusammen mit seinem Inhalt, indem der von uns gespeicherte Wert$_
plus der vom Benutzer angegebene Code Q plusprint
die Ausgabe gedruckt wird. (Leider können wir nicht verwendensay
; es fügt eine neue Zeile hinzu, und das ist in Quines relevant.)Die Holzkohle
Der "Sinn" dieser Antwort bestand darin, in Perl verallgemeinerte Quines zu erzeugen. Nachdem ich also eine Golfstrategie dafür entwickelt hatte (eine, die ich in vielen anderen Antworten verwendet habe), war es an der Zeit, das Programm P zu schreiben, das im Grunde genommen nur Ersatz ist eine Zeichenfolge in eine Vorlage. Was ich hier wollte, war eine Sprache, die gut darin war, konstante Zeichenfolgen zu drucken (im Idealfall ein wenig zu komprimieren) und Benutzereingaben in sie zu interpolieren.
Nachdem ich ein paar ausprobiert hatte, entschied ich mich für Charcoal, das ich noch nie benutzt hatte (und das wirklich etwas Dokumentation vertragen könnte). Es wurde für ASCII-Kunst entwickelt, kann aber auch Zeichenfolgen in einer Dimension schreiben. ASCII - Zeichen werden in Charcoal buchstäblich gedruckt, was bedeutet, dass für das Drucken von konstanten Zeichenfolgen kein Boilerplate erforderlich ist
S
erforderlich Befehl können Sie eine Zeichenfolge interpolieren, die von Benutzereingaben in das Programm übernommen wurde.Es ist jedoch möglich, etwas kürzer zu werden. Der Perl Universal Quine-Konstruktor enthält zwei ziemlich lange, sich wiederholende Abschnitte. Wir können sie also mit dem
A
Befehl Variablen zuweisen (z. B.A…α
der Variablen zuweisen)α
) und die Variablen einfach mit ihren Namen in die Zeichenfolge interpolieren, über die wir drucken. Das spart ein paar Bytes, wenn Sie den String nur buchstäblich schreiben.Leider fügt Charcoal dem Programm auch eine neue Zeile hinzu, aber das ist keine große Sache. Es kostet lediglich zwei Bytes
\n
, um diese Zeilenumbruchzeile auch der Eingabe von Q hinzuzufügen.Beispiel
Wenn wir die Eingabe
$_=reverse
(die eine Zeichenfolge umkehrt) geben, erhalten wir die folgende Ausgabe:Probieren Sie es online!
Das ist ein Quine-Alike, der seine Quelle wie erwartet rückwärts druckt.
quelle
Gelee → Unterlast , 15 Bytes
Probieren Sie es online!
Nimmt die Eingabe-Unterladefunktion Q als befehlsähnliches Argument. Q muss Eingaben vom Stapel nehmen und die Ausgabe an den Stapel senden, ohne zu versuchen, tiefere Stapelelemente zu untersuchen (da sie nicht existieren).
Erläuterung
Die Unterlast
Der hier verwendete universelle Unterlast-Quine-Konstruktor ist:
Der größte Teil des Programms ist ein einzelnes Literal. Wir folgen dem, indem wir
:^
es kopieren und dann eine Kopie auswerten (wobei die andere Kopie auf dem Stapel verbleibt).Wenn das Literal mit der Auswertung beginnt, führen wir
a
(Escape, wodurch es wieder in die gleiche Form wie das ursprüngliche Programm A gebracht wird) und(:^)*
(das angehängt wird:^
) aus und rekonstruieren so den gesamten Quellcode des Programms. Wir können dann die Funktion Q ausführen, um diese auf beliebige Weise zu transformieren, und das Ergebnis mit ausgebenS
.Das Gelee
Diesmal kann ich Charcoal nicht verwenden, da ein validierender Underload-Interpreter am Ende des Programms abstürzt, wenn das Programm mit einem Zeilenumbruch endet. (Einige Unterlast-Interpreter, wie der von TIO, erzwingen diese Regel nicht, aber ich wollte ordnungsgemäß portierbar sein.) Leider fügt Charcoal seiner Ausgabe natürlich nachgestellte Zeilenumbrüche hinzu. Stattdessen habe ich Jelly verwendet, das in einfachen Fällen wie diesem fast so knapp ist. Das Programm besteht aus einem Listenliteral mit zwei Elementen (
““”
) und fügt sie an der Eingabe (j
) zusammen, wodurch die Benutzereingabe in das Programm interpoliert wird.Beispiel
Mit der Eingabe
:S^
(Kopie drucken, Original auswerten) erhalten wir folgendes Unterlastprogramm:Probieren Sie es online!
Dies druckt sich auf interessante Weise unendlich oft von selbst aus: Nach dem normalen Quine-Verhalten wird es
eval
auf einer Kopie des ausgegebenen Dokuments ausgeführt. Dadurch wird das gesamte rekonstruierte Programm auf unbestimmte Zeit erneut ausgeführt (Unterlast ist schwanzrekursiv). Quinieren Sie sich selbst und macheneval
Sie eine Endlosschleife in Underload.quelle
RProgN 2 , 11 Bytes
Programmerklärung
Quine Explination
Das erzeugte Quine ist einfach, verwendet jedoch die Funktionalität von nicht angepassten Funktionshandlern in RProgN2, um ein kurzes und süßes Quine zu erstellen, das als "Looping" -Quine bezeichnet wird. Es ist ein überraschend ähnliches Konzept wie ein <> <Quine.
Natürlich kann aufgrund der Struktur dieses Quines alles andere als echte No-Ops (die nicht verkettet werden) nach der Verkettungsfunktion und gesetzt werden
Einige Quinten
{`{.i}{
: Ausgänge{}i.{`{
.i
Ist nur die "inverse" Funktion, so gibt sich dieses Programm umgekehrt aus.{`{.S§.}{
: Ausgänge..S`{{{}§
.S
wandelt die Zeichenfolge in einen Zeichenstapel um,§
sortiert den Stapel lexografisch, fügt ihn dann.
wieder zusammen und gibt sich selbst sortiert aus.Probieren Sie es online!
quelle