2 Katzen in einem Quine


30

Herausforderung

Erstellen Sie zwei Programme, A und B, die beide Katzenprogramme in derselben Sprache sind. In der Verkettung sollte AB (auch in derselben Sprache) ein Quine sein.

Angenommen, hellound worldsind beide Katzen Programme in Sprache XYZ. Obhelloworld eine Quine in dieser Sprache ist, dann ist Ihre Lösung gültig.

Für diejenigen unter Ihnen, die mit Katzen und Quines nicht vertraut sind, gibt ein Cat-Programm genau das aus, was ihm über stdin gegeben wurde, und ein Quine-Programm gibt seinen eigenen Quellcode aus.

Wertung und Regeln

  • Die Gesamtbytezahl des verketteten AB-Programms ist Ihre Punktzahl. Da dies Codegolf ist, gewinnt die niedrigste Punktzahl.
  • Standardlücken sind verboten
  • Die Eingabe muss von stdin genommen werden und die Ausgabe muss auf stdout gehen.
  • Die cat-Programme müssen keine Argumente entgegennehmen. Sie müssen nur stdin nach stdout kopieren.
  • Das quine sollte funktionieren, wenn das Programm keine Eingabe erhält, aber für andere Eingaben nicht richtig funktionieren muss (aber möglicherweise).
  • Das Quine muss nicht beendet werden, vorausgesetzt, es gibt genau seinen Quellcode einmal aus, nicht mehr.
  • Das Quine muss mindestens ein Byte lang sein.
  • A und B können dasselbe Programm sein.
  • BA muss kein quines oder gar gültiges Programm sein.

Ich denke nicht, dass Sie A und B die gleiche Programmregel haben sollten
Muhammad Salman

2
@ MuhammadSalman Meine ursprüngliche Idee war, ein Katzenprogramm zu verdoppeln, um es in ein Quine zu verwandeln. Ich wollte nur die Tür zu einfacheren Lösungen öffnen, weil ich nicht ganz sicher war, ob dies möglich war. Sieht so aus, als hätte ich mich in beiden Punkten geirrt, aber damit bin ich einverstanden.
Beefster

3
Sie sollten wahrscheinlich hinzufügen, dass ABdies nicht leer sein darf, da viele Sprachen eine 0-Byte-Katze haben, die eine 0-Byte-Quine zulässt.
DJMcMayhem

9
@DJMcMayhem Eine 0-Byte-Quine wäre jedoch keine gültige Quine.
Nissa

4
Was ist ein Katzenprogramm?
Pedro A

Antworten:


32

V , 2 + 2 == 4 Bytes

2i2i

Probieren Sie das Quine!

Probieren Sie die Katze!

A ist2i

B ist auch2i

Wie funktioniert es?

Zunächst einige Erklärungen zur Funktionsweise von V. Eine bemerkenswerte Sache, die diese Antwort ermöglicht, ist, dass in V das leere Programm ist eine Katze Programm. Dies ist kein Sonderfall, sondern hängt mit der Funktionsweise von V zusammen. Beim Start werden alle Eingaben in einen "Puffer" geladen, jeder Befehl ändert den Puffer auf irgendeine Weise, und wenn das Programm abgeschlossen ist, wird der Puffer implizit gedruckt. Dies bedeutet, dass jede Folge von NOPs auch ein Katzenprogramm ist.

Der iBefehl bedeutet, dass Sie in den Einfügemodus wechseln . Dies bedeutet, dass jedes Zeichen, das auf ein ifolgt, in den Puffer eingefügt wird. Mit einer vorangestellten Zahl wird dieser Text n- mal dupliziert .

Dies bedeutet, dass für das cat-Programm nichts zum Puffer hinzugefügt und gedruckt wird, während es gelesen wurde. Mit anderen Worten:

        " (Implicitly) Load all input
2       " 2 times,
 i      " Insert the following text into the buffer...
        " (nothing)
        " (Implicitly) Print the buffer

Aber für das Quine gibt es Text nach dem i:

2       " 2 times,
 i      " Insert the following text into the buffer...
  2i    "   "2i"
        " (Implicitly) Print the buffer

Freche Nichtantwort

V , 0 Bytes

Probieren Sie es online!

A ist das leere Programm.

B ist auch das leere Programm.

: P


21
Jede andere Sprache: Oy, wir sind in eine Sackgasse geraten! . V: * postet Standardquine * .
Erik der Outgolfer

13

Ruby, 71 Bytes

2;puts (<<2*2+?2)[/.+2/m]||$<.read
2;puts (<<2*2+?2)[/.+2/m]||$<.read
2

Kann wie folgt in Katzen aufgeteilt werden:

2;puts (<<2*2+?2)[/.+2/m]||$<.read
2

und

;puts (<<2*2+?2)[/.+2/m]||$<.read
2

Die beiden Katzen sind identisch, mit Ausnahme der führenden 2, die in allen drei Programmen ein No-Op ist. Das <<2ist ein Herestring, was bedeutet, dass alles, was in der nächsten Zeile beginnt, bis zu einer abschließenden 2 in einer eigenen Zeile, eine Zeichenfolge ist, die wir mit sich selbst verketten ( *2) und eine abschließende 2 anfügen. Bei den Katzen ist der Herestring gut geformt, aber leer. $<.readDaher stimmt der reguläre Ausdruck nicht mit ihm überein, und wir gehen zum Ausdruck über und geben STDOUT aus. Sobald wir die Katzen ansprechen, endet die Zeichenfolge jedoch erst in der dritten Zeile. Der reguläre Ausdruck stimmt also überein, und wir schließen die Quine kurz und geben sie aus.


11

Pyth, 29 Bytes (5 + 24) 27 Bytes (5 + 22)

pz=T0?TzjN*2]"pz=T0?TzjN*2]     # Quine
pz=T0                           # Cat A
     ?TzjN*2]"pz=T0?TzjN*2]     # Cat B

Das hat Spaß gemacht.
Versuchen Sie das Quine hier
Versuchen Sie die erste Katze hier
Versuchen Sie die zweite Katze hier

Erklärungen

Cat A
pz=T0
pz       Print the input.
  =T0    (Irrelevant for cat)

Cat B
?TzjN*2]"pz=T0?TzjN*2]
?Tz                      If T (10) is truthy, output the input.
   jN*2]"pz=T0?TzjN*2]   (Irrelevant for cat)

Quine
pz=T0?TzjN*2]"pz=T0?TzjN*2]
pz                            Print the (empty) input (without a newline).
  =T0                         Set T to 0.
     ?Tz                      If T (0) is truthy, output the input.
             "pz=T0?TzjN*2]   Otherwise, get this string...
          *2]                 ... take two copies...
        jN                    ... and join them with a quote.

11

C # (Visual C # -Compiler) , 551 Byte

A: 95 Bytes

class A{public static int i=2;static void Main(string[]args){System.Console.Write(args[0]);}}//

Probieren Sie es online!

B: 438 + 18 Bytes

class A{public static int i=0;}
class B{static void Main(string[]args){if(A.i<1){System.Console.Write(args[0]);return;}var a=@"class A{{public static int i=2;static void Main(string[]args){{System.Console.Write(args[0]);}}}}//class A{{public static int i=0;}}
class B{{static void Main(string[]args){{if(A.i<1){{System.Console.Write(args[0]);return;}}var a=@{0}{1}{0};System.Console.Write(a,'{0}',a);}}}}";System.Console.Write(a,'"',a);}}

Probieren Sie es online!

A + B: 533 + 18 Bytes

class A{public static int i=2;static void Main(string[]args){System.Console.Write(args[0]);}}//class A{public static int i=0;}
class B{static void Main(string[]args){if(A.i<1){System.Console.Write(args[0]);return;}var a=@"class A{{public static int i=2;static void Main(string[]args){{System.Console.Write(args[0]);}}}}//class A{{public static int i=0;}}
class B{{static void Main(string[]args){{if(A.i<1){{System.Console.Write(args[0]);return;}}var a=@{0}{1}{0};System.Console.Write(a,'{0}',a);}}}}";System.Console.Write(a,'"',a);}}

Probieren Sie es online!

A und B nehmen Eingaben als Befehlszeilenargument entgegen. A + B ignoriert alle Eingaben. 18 Bytes auf B und A + B werden für die hinzugefügt/p:StartupObject=B an MSBuild gesendete Option werden . Es ist nur für A + B unbedingt erforderlich, aber es schien zu schummeln, es nicht auch in B zu haben. Auf diese Weise sind die Compiler-Flags für A + B die Compiler-Flags für A (keine) plus die Compiler-Flags für B.

Erläuterung

Programm A ist unkompliziert. Klasse A enthält eine (nicht verwendete) statische Variable, die mit iinitialisiert wurde 2, und gibt ihr erstes Argument aus, wenn sie ausgeführt wird. Das //am Ende ist wichtig für den A + B-Code, tut aber nichts in A selbst.

Programm B ist für sich genommen seltsam, aber im Wesentlichen dasselbe. Es erstellt eine Klasse A, die eine statische Variable enthält, die mit iinitialisiert wurde 0, und führt dann die Main-Methode der Klasse B aus, die dasselbe wie Program A because ausführtA.i kleiner als 1 ist, und vor den seltsamen Elementen zurückgibt. Die Zeilenumbrüche sind hier nicht notwendig, aber wichtig für A + B.

In Kombination //kommentiert das von Programm A die Klasse-A-Deklaration von Programm B aus, aber wegen des Zeilenumbruchs ist Klasse B in Ordnung, sodass stattdessen A.iauf den 2Wert von Programm A verwiesen werden kann. Das Compiler-Flag veranlasst das Programm, B.Main () auszuführen, da A.Main () ebenfalls vorhanden ist. Das Ergebnis ist, dass Programm A + B sein Argument nicht ausgibt, sondern stattdessen zum folgenden Segment von B.Main () geht, das im Grunde nur das Standard-C # -Quine ist .


1
"Die Katze Programme ... müssen stdin zu stdout kopieren"
Jakob

9

Haskell , 116 + 20 = 187 175 174 136 Bytes

Ein paar Bytes wurden gespeichert, seit Ørjan Johansen es mir gezeigt hat interact

Katze 1

g=";main|idmain<-(++\"g=\"++show g++g)=interact idmain|1>0=interact id";main|idmain<-(++"g="++show g++g)=interact id

Probieren Sie es online!

Katze 2

main|1>0=interact id

Probieren Sie es online!

Quine

g=";main|idmain<-(++\"g=\"++show g++g)=interact idmain|1>0=interact id";main|idmain<-(++"g="++show g++g)=interact idmain|1>0=interact id

Probieren Sie es online!


Das Grundprinzip bei der Arbeit besteht darin, dass wir den Namen der Funktion, mit der wir interagieren, von anach ändern, wenn wir die zweite Katze zur ersten hinzufügen idmain. Da interact ides sich um eine Katze handelt, möchten wir idmainmir eine Funktion geben, die eine Quine zurückgibt. Die naheliegende Lösung wäre jedoch zu verwenden const, da wir davon ausgehen können, dass die Eingabe auch leer ist (++). Von hier aus finden wir den Quellcode auf ziemlich standardmäßige Weise, wir haben eine Variable g, die den Quellcode codiert, und wir verwenden einen speziellen Wrapper, um ihn in String- und Code-Form zu drucken. Es gibt eine kleine Ausnahme, bei der wir unseren Encoder in den Vordergrund stellen müssen, da wir bereits mit enden müsseninteract id . Dies bedeutet ein Extrag=wird nicht verschlüsselt und muss manuell gehandhabt werden. Unsere nächste Katze ist ein ziemlicher Standard, außer dass wir einen gültigen Code erstellen müssen, wenn sie am Ende der anderen Katze angeheftet wird, sodass wir beide Katzen als Musterwächter benötigen.

Alternative Strategie, 43 + 105 = 186 148

Katze 1

g="";main|idmain<-(++g++show g)=interact id

Probieren Sie es online!

Katze 2

main|1>0=interact id where g="g=\"\";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="

Probieren Sie es online!

Quine

g="";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="g=\"\";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="

Probieren Sie es online!


1
Sie können durch das Ersetzen dass einiges verkürzen getContents+ putStrmit interact id. Probieren Sie es online! (Die Quine funktioniert nicht mehr mit nicht-leeren Eingaben, wodurch die Verwendung eines (++ ...)Abschnitts für die idmain.)
Ørjan Johansen

@ ØrjanJohansen Danke! Ich wusste nichts davon interact, ich denke, das liegt daran, dass ich selten IO-Sachen mit Haskell mache. Ich habe den Beitrag bearbeitet.
Wheat Wizard

8

Python 3, 286 Bytes

Mein erster Python Golf und mein erster Quine! Nicht sehr elegant, aber es funktioniert.

Programm A (238 Byte)

from atexit import*;s="from atexit import*;s=%r;register(lambda:print(end='b'in globals()and s%%s or open(0).read()));b=0\nif's'not in vars():print(end=open(0).read())";register(lambda:print(end='b'in globals()and s%s or open(0).read()));

(kein abschließender Zeilenumbruch)

Programm B (48 Bytes)

b=0
if's'not in vars():print(end=open(0).read())

(kein abschließender Zeilenumbruch)

Probieren Sie es online

Danksagung

  • -24 Bytes dank Jo King
  • -82 Bytes dank Jo King

Sie können end=open...und verwenden, %ranstatt %snicht die Zeilenumbrüche und Zitate zu tun
Jo King

Cool, ich wechselte zu %r. Ich bin mir nicht sicher, was du mit der Newline meinst.
Jakob

1
Anstatt %seinen Zeilenumbruch zu formatieren, können Sie auch nur das Literal verwenden \n. Sie können auch ;zum Teilen von Anweisungen anstelle von verwenden \n(außer, dass die Anweisungen ifin einer eigenen Zeile stehen müssen). %kann dadurch in der Zeichenkette maskiert werden %%. Das einzige Argument, das zum Formatieren der Zeichenfolge benötigt wird, ist die Zeichenfolge selbst. Alles andere kann gestreift werden
Jo King,

1
Programm B (und der Text dafür) kann locals()2 Bytes speichern.
Jonathan Allan

6

C ++ (clang) , 313 + 102 = 415 Bytes

Programm A (endet in einer neuen Zeile):

#include<cstdio>
#define Q(x,y)#x,B=#y;x
int c;auto I="#include<cstdio>",A=Q(int main(){if(c)printf("%s\n#define Q(x,y)#x\",\"#y;x\nint c;auto I=\"%s\",A=Q(%s,)\n#ifdef Q\nint n=++c;\n#else\n%s\n%s\n#endif",I,I,A,I,B);else while((c=getchar())>=0)putchar(c);},int c;int main(){while((c=getchar())>=0)putchar(c);})

Programm B (endet nicht in Newline):

#ifdef Q
int n=++c;
#else
#include<cstdio>
int c;int main(){while((c=getchar())>=0)putchar(c);}
#endif

Nicht besonders hinterhältig, und C ++ eignet sich wie üblich nicht so gut zum Quinten. Es wird mich nicht wundern, wenn es Möglichkeiten gibt, Bytes hier und da von der gleichen Idee abzuheben. Der einzige kleine Haken ist, das Verhalten von etwas zu ändern, nachdem es definiert wurde, und ein dynamischer Variableninitialisierer mit Nebeneffekt erledigt den Trick. (Kann dies sogar in C ohne Compilererweiterungen durchgeführt werden?)

Probieren Sie es online aus: A , B , AB

(Das einzige Problem bei der Portabilität, das mir bekannt ist, besteht darin, dass das Programm davon ausgeht, dass <cstdio>Namen sowohl im globalen Namespace als auch in gesetzt werden std.)


5

Befunge-98 (FBBI) , 8 + 15 = 23 Bytes

A + B: (funktioniert nur für keine Eingabe)

+9*5~,#@#@~,9j>:#,_:@#"

Probieren Sie es online!

EIN:

+9*5~,#@

Probieren Sie es online!

B:

#@~,9j>:#,_:@#"

Probieren Sie es online!


Ich habe mich gefragt, ob jemand eine befunge Antwort schaffen würde. Es ist schade, dass dies nicht 2D ist: - /
Beefster

@ Beefster ja. Das Problem ist, dass es ziemlich schwierig ist, eine 2D-Quine zu erstellen. Vielleicht arbeite ich aber an etwas
MildlyMilquetoast

5

Python 3 , 100 + 37 = 137 Bytes

Programm A:

s='s=%r;print(end=open(0).read())#print(end=open(0).read())\nprint(s%%s)';print(end=open(0).read())#

Probieren Sie es online!

Programm B:

print(end=open(0).read())
print(s%s)

Probieren Sie es online!

Machen Sie Quine AB

s='s=%r;print(end=open(0).read())#print(end=open(0).read())\nprint(s%%s)';print(end=open(0).read())#print(end=open(0).read())
print(s%s)

Probieren Sie es online!

Funktioniert nur, wenn die Eingabe leer ist, andernfalls wird die Eingabe der Ausgabe vorangestellt.


Die Anführungszeichen sollten einfach sein.
Jonathan Allan

Absturz ist erlaubt?
Jakob

@ Jakob Die Frage sagt nicht, dass Abstürzen nicht ist zulässig sind, und die Ausgabe an STDERR wird normalerweise ignoriert
Jo King

OK Fair genug. Clevere Verknüpfungen!
Jakob

4

Attache , 15 + 126 = 141 Bytes

EIN:

AllInput[]|Echo

Probieren Sie es online!

B:

@{If[_,s.="AllInput[]|Echo@{If[_,s.=%s;;Printf[s,Repr!s],AllInput[]|Echo]es}|Call";;Printf[s,Repr!s],AllInput[]|Echo]es}|Call

Probieren Sie es online!

A + B:

AllInput[]|Echo@{If[_,s.="AllInput[]|Echo@{If[_,s.=%s;;Printf[s,Repr!s],AllInput[]|Echo]es}|Call";;Printf[s,Repr!s],AllInput[]|Echo]es}|Call

Probieren Sie es online!

Erläuterung

Jedes der Katzenkodierungen AllInput[]|Echoist ein einfaches Katzenkodierungsprogramm.B ist die Hauptquinphase; Alleine ist es eine vektorisierte Funktion (durch unary @), die ohne Eingaben aufgerufen wird (als aufgerufen wird |Call). Somit wird die erste Bedingung If[_,A,B]ausgeführt B, was einfach istAllInput[]|Echo .

Wann A + B ausgeführt wird, @wird Unary @aufgrund der EchoVerschmelzung mit dem Lambda binär :

AllInput[]|Echo@{If[_, ...

Dies bedeutet nun, dass das Lambda ausgeführt wird, bevor Echoes ausgeführt wird. Zurück zur Bedingung, diese Funktion hat jetzt alle STDIN als Argument. Also, If[_,A,B]führt ausA , was das Standard-Quine-Framework ist.


3

Stax , 16 + 12 = 28 Bytes

Katze 1:

"yi|d|ca34b4lr"y

Führen Sie es aus und debuggen Sie es

"yi|d|ca34b4lr"y Full program, implicit input
"yi|d|ca34b4lr"  Push the string
               y Push raw input
                 Implicit output of top item

Katze 2:

i|d|ca34b4lr

Führen Sie es aus und debuggen Sie es

i|d|ca34b4lr Full program, implicit input
i            Don't parse input (prefix directive)
 |d          Push main stack depth, always zero
   |c        Cancel because top item is falsy, and implicitly print
     a34b4lr Never executed

Quine:

"yi|d|ca34b4lr"yi|d|ca34b4lr

Führen Sie es aus und debuggen Sie es

"yi|d|ca34b4lr"yi|d|ca34b4lr Full program
"yi|d|ca34b4lr"              Push the string
               y             Push input
                i            No-op
                 |d          Push main stack depth, i.e. 2
                   |c        Do nothing because top is truthy
                     a       Get the string to the top
                      34     Push 34 (charcode of ")
                        b    Copy both
                         4l  Listify top 4
                           r Reverse
                             Implicit output

3

Katze 1:

Lua , 41 Bytes

a=io.read;while a(0)do io.write(a(1))end;

Probieren Sie es online!


Katze 2:

Lua , 70 Bytes

if a then io.input(arg[0])end;a=io.read;while a(0)do io.write(a(1))end

Probieren Sie es online!


Quine:

Lua , 111 Bytes

a=io.read;while a(0)do io.write(a(1))end
if a then io.input(arg[0])end;a=io.read;while a(0)do io.write(a(1))end

Probieren Sie es online!

io.input(arg[0]) In Cat 2 wird die aktuelle Datei als Standardeingabe festgelegt. Infolgedessen druckt die Katze den Quellcode


1
Willkommen bei PPCG
Muhammad Salman

Sie können ein Byte in Katze 1 speichern, indem Sie das letzte Semikolon entfernen?
Muhammad Salman

1
Leider ist das Lesen der aktuellen Datei eine Standardlücke. Aber netter Versuch trotzdem.
Beefster


0

JavaScript (Node.js) , 199 Byte


a=()=>console.log(require('fs').readFileSync(0)+'');a();var a=a||0;b=()=>console.log(require('fs').readFileSync(0)+'');!a?b():c=()=>console.log(`a=${a};a();var a=a||0;b=${b};!a?b():c=${c},c()`),c()

Probieren Sie es online!

Kat A, 57 Bytes


a=()=>console.log(require('fs').readFileSync(0)+'');a();

Probieren Sie es online!

Kat. B, 142 Bytes

var a=a||0;b=()=>console.log(require('fs').readFileSync(0)+'');!a?b():c=()=>console.log(`a=${a};a();var a=a||0;b=${b};!a?b():c=${c},c()`),c()

Probieren Sie es online!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.