Mache eine verwobene Quine

17

Ihre Aufgabe ist es, ein Programm zu erstellen, das sich beim Ausführen selbst als Ausgabe ausgibt (dies wird als Quine bezeichnet). Dieses Quine muss jedoch, wenn es nmal kopiert wird, das Quine zurückgeben, wobei jedoch jedes seiner Zeichen in Ortszeiten dupliziert nwird, wobei nes sich um eine positive Ganzzahl handelt.

Wenn Ihr ursprüngliches Programm ist Derp:

Derp -> Derp (must return itself as output to be a quine)

DerpDerp -> DDeerrpp
(the "Derp" is copied twice, so each character in the output has to be copied twice)

DerpDerpDerp -> DDDeeerrrppp
etc. etc.

Denken Sie daran, dass Sie in Ihrem "Basis" -Programm Leerzeichen verwenden dürfen, diese werden jedoch beim "Verweben" berücksichtigt. Sagen Sie, Ihr Programm ist

Derp 
{newline}

(Die neue Zeile steht für eine abschließende neue Zeile und nach der steht ein zusätzliches Leerzeichen Derp.) Beim duplizieren werden

Derp 
Derp 
{newline}

Sie müssen ausgeben

DDeerrpp  
{newline}
{newline}

Denken Sie daran, dass 2nach dem ein zusätzliches Leerzeichen eingefügt wird DDeerrpp.

Regeln und Spezifikationen:

  • Ihr Programm muss mindestens zwei verschiedene Zeichen enthalten (dies bedeutet, dass Ihr Code mindestens 2 Byte lang sein muss).
  • Es gelten die üblichen Regeln für Quine .

Das ist , also gewinnt der kürzeste Code in Bytes!

Clismique
quelle
1
"Es gelten die Standardregeln" - heißt das, dass der Quellcode nicht gelesen werden darf?
FlipTack
@FlipTack Es bedeutet, dass - lesen Sie den Link für weitere Informationen.
Clismique

Antworten:

12

Spaltung , 6 Bytes

'!+OR"

Probieren Sie es online! Versuchen Sie es mit zwei Kopien! Versuchen Sie es mit drei!

Erläuterung

Dies ist nur die Fission Standard-Quine . Es funktioniert für diese Herausforderung, weil Fission explizite Einstiegspunkte in das Programm hat. Insbesondere fügen wir durch Duplizieren des Programms ein weiteres hinzuR hinzu, das ein weiteres Atom (Anweisungszeiger) hinzufügt. Da der Quellcode toroidal ist, ändert sich der ausgeführte effektive Code nicht anders - für jedes Atom sieht der Code lokal immer noch gleich aus. Die Atome werden jedoch im Lock-Schritt ausgeführt, sodass die von ihnen gedruckten Objekte verschachtelt werden und wir eine zusätzliche Kopie jedes Zeichens in der Ausgabe erhalten.

Der Vollständigkeit halber werde ich nur kurz wiederholen, wie das Programm selbst funktioniert. Unabhängig davon, ob wir das Programm wiederholen oder nicht (zB '!+OR"'!+OR"'!+OR"), sieht jedes Atom den folgenden Code:

R"'!+OR"'!+O

Der "String-Druckmodus wird '!+ORumgeschaltet , so dass das Programm mit dem direkten Drucken zu STDOUT beginnt , das bis auf das Anführungszeichen alles Quine ist. Dann '!setzt die Masse des Atoms mit dem Zeichencode !, +Inkrementen es, die gibt ", und Oes druckt , während gleichzeitig das Atom zu zerstören. Das Programm wird dann beendet, da keine Atome mehr vorhanden sind.

Martin Ender
quelle
11

Python 2.7, 377 310 304 194 191 Bytes!

Dies ist mein erstes Golf, also habe ich nicht erwartet, dass es zu gut wird. Aber ich fand das Konzept in der Lösung, die ich mir ausgedacht habe, etwas witzig, also poste ich es trotzdem.

def f():
 import threading as T,inspect as i;global t,a,i
 try:t.cancel()
 except:a=0
 a+=1;t=T.Timer(1,d);t.start()
def d():print''.join(c*a for c in i.getsource(f)+i.getsource(d)+"f()")
f()

In der Tat ist dies ein Quin; Sie können es hier versuchen . Es missbraucht das Inspect-Modul ziemlich stark.

Wenn wir versuchen, es mit demselben Quellcode x2 auszuführen, erhalten wir auch die richtige Ausgabe. das kannst du hier probieren . x3, x4 usw. funktionieren alle wie erwartet.

Ungolfed mit Erklärung:

def f():                                   # Defines a central function f
    import threading as T,inspect as i     # Imports threading and inspect
    global t,a,i                           # Global vars
    try:
        t.cancel()                         # Tries to cancel Timer from previous code
    except:
        a = 0                              # Reached when code is 1st copy; initializes a.
    a += 1                                 # a++; this is the number of copies thus far.
    t = T.Timer(1,d)               # Creates, then starts a timer to call function
    t.start()                              # d in 1 second.

def d():                                   # Prints out the source code; the quine part.
    print''.join(c*a for c in i.getsource(f)+i.getsource(d)+"f()")

f()                                        # Calls f()!
Calconym
quelle
Ist das nicht ein Betrug Quine, wie es den Quellcode seiner eigenen Funktionen liest mit inspect? (siehe entsprechenden Metapost ). In PPCG haben wir spezifische Definitionen, was eine Quine gültig macht, und das 'Lesen der Quelle' wird normalerweise als Betrug angesehen.
FlipTack
@FlipTack Ich bin mir nicht sicher, ob das Überprüfen einer Funktion mit dem Lesen des Quellcodes identisch ist. Quines in JavaScript und Stack-basierten Sprachen tun dies die ganze Zeit.
Dennis
In Ordnung :). Ich habe eine Syntaxhervorhebung für Ihren Beitrag hinzugefügt. Gute Idee mit Threading!
FlipTack
import threading,inspect as ican beimport threading as T,inspect as i
nedla2004 29.12.16
@FlipTack Ups, danke.
Calconym
3

CJam , 19 Bytes

{]W=s"_~"+T):Te*}_~

Probieren Sie es online!

Wie es funktioniert

{               }_~  Define an anonymous code block (function).
                 _~  Push a copy, and execute the copy.
 ]W=                 Wrap the entire stack in an array and select its last element.
                     This discards whatever was on the stack before the original
                     code block, which is needed for subsequent iterations.
    s"_~"+           Cast the code block to string, push "_~", and concatenate.
                     This pushes the stringified source code on the stack.
          T):T       Push T (initially 0), increment it, and save the result in T.
              e*     Repeat each character in the stringified source code T times.
Dennis
quelle
Was ... wie ... so schnell ... bitte erkläre den Code, damit du mir die Methoden von CJam beibringen kannst.
Clismique
@ Qwerp-Derp Ich habe eine Erklärung hinzugefügt.
Dennis
3

RProgN , 66 Bytes

Bedeutendes Leerzeichen ist der Tod von mir

[ "[ %q ] F 0 1 + `0 = `. { 0 m } R " ] F 0 1 + `0 = `. { 0 m } R 

Erklärt

[ "[ %q ] F 0 1 + `0 = `. { 0 m } R " ] F 0 1 + `0 = `. { 0 m } R   #
[                                                                   # Pop whatever is already on the stack, if anything.
  "[ %q ] F 0 1 + `0 = `. { 0 m } R "                               # This string contains basically the entire function.
                                      ] F                           # ] F duplicates the string, and then F formats it, which in this case puts the first string into the second at %q, surrounded by qoutes.
                                          0 1 + `0 =                # I needed an Incrementer, so I chose 0. 0, is conveniently, pre initilized at 0. And because RProgN is horrifying, you can remap the number functions as they're just more variables. So this increments 0 every time the group is called.
                                                     `. { 0 m } R   # Replace each character with itself repeated '0' times. Because '0' is an incrementer, each time the script is called, the amount of times the characters are repeated increase.

Guter Herr, ich bin ein Monster ...

Probieren Sie es online!

Ein Taco
quelle
Obwohl es ~["[%q]F01+`0=`.{0m}R"]F01+`0=`.{0m}Rim Allgemeinen gut funktioniert, ist es auch keine gültige Lösung, da es keine Möglichkeit gibt, den ZSS-Marker zu replizieren.
ATaco
2

Perl 5, 107 Bytes

$_=q[$_=q[S];s/S/$_/;$a++;END{s/./$&x$a/eg;print if$a;$a=0}];s/S/$_/;$a++;END{s/./$&x$a/eg;print if$a;$a=0}

Ungolfed:

$_ = '...INSERT_SOURCE_HERE...';      # Standard quine
s/INSERT_SOURCE_HERE/$_;
$a++;                                 # Count the number of repetitions
END {
    s/./$&x$a/eg;                     # Interweave
    print if $a;                      # Print...
    $a=0;                             # ...but only once
}

Probieren Sie es online!

Joey Marianer
quelle
2

Python 3 , 122 121 112 Bytes

s='try:from atexit import*;n+=1\nexcept:n=1;register(lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s])';exec(s);

Probieren Sie es online aus: eine Kopie | zwei Exemplare | drei Exemplare | vier Exemplare mit automatischer Überprüfung

Wie es funktioniert

Dies verwendet das Standard-Python-Quine: Speichern Sie den Code, den Sie ausführen möchten, in einer Variablen (als Zeichenfolge); Fügen Sie eine Logik in diese Zeichenfolge ein, um sich selbst, alles davor und alles danach zu drucken. Führen Sie dann diese Zeichenfolge aus.

Der Code, der über die Zeichenfolge s ausgeführt wird, ist der folgende.

try:from atexit import*;n+=1
except:n=1;register(lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s])

Die erste Zeile importiert bedingungslos das atexit- Modul , mit dem wir einen Exit-Handler registrieren können. Der Versuch, dasselbe Modul mehrmals zu importieren, hat keinerlei Auswirkungen auf das Skript. Dann wird versucht, die Variable n zu inkrementieren , um zu verfolgen, wie viele Kopien des Quellcodes ausgeführt wurden.

Die zweite Zeile wird nur ausgeführt, wenn die erste einen Fehler enthält. Dies wird in der ersten Iteration der Fall sein, da n immer noch undefiniert ist. In diesem Fall initialisieren wir n als 1 und registrieren ein Lambda, das die eigentliche Magie ausführt.

Der registrierte Exit-Handler

lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s]

wird kurz vor Programmende aufgerufen. Das Lambda selbst erzeugt die String "s=%r;exec(s);"%s- %rerzeugt eine String - Darstellung des rechten Arguments ( s ), die alles zwischen den einfachen Anführungszeichen und den Anführungszeichen selbst enthält - dann seine Zeichen iteriert. Für jedes Zeichen c drucken wir einfach n Kopien von c . Passing c*nals benanntes Argument endan printMitteln , die kein Zeilenvorschub angehängt wird.

Dennis
quelle
1

CJam , 14 Bytes

{s"_~"+]:.+}_~

Probieren Sie es online!

Erklärungen

{s"_~"+]:.+}_~
{s"_~"+    }_~ Basic quine operator.
       ]:.+    Append each character to corresponding element of the previous result if existed.
jimmy23013
quelle