Hacer una quine entrelazada

17

Su tarea es crear un programa que, cuando se ejecuta, se devuelve como salida (esto se conoce como quine). Sin embargo, esta quine debe, cuando se copia nveces, devuelve la quine, pero con cada uno de sus caracteres duplicados en el lugar nveces, donde nes un entero positivo.

Si su programa original es 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.

Tenga en cuenta que se le permite tener espacios en blanco en su programa "base", pero se cuentan cuando se "entrelazan". Digamos que tu programa es

Derp 
{newline}

(La nueva línea significa una nueva línea final, y hay un espacio adicional después de Derp). Cuando se duplica para convertirse

Derp 
Derp 
{newline}

Debe salida

DDeerrpp  
{newline}
{newline}

Tenga en cuenta que hay 2espacios adicionales después delDDeerrpp .

Reglas y especificaciones:

  • Su programa debe contener al menos dos caracteres distintos (lo que implica que su código debe tener al menos 2 bytes de longitud).
  • Se aplican las reglas estándar de quine .

Este es el , por lo que gana el código más corto en bytes.

clismique
fuente
1
"Se aplican reglas estándar": ¿eso significa que no se debe leer el código fuente?
FlipTack
@FlipTack Significa eso: lea el enlace para obtener más información.
clismique

Respuestas:

12

Fisión , 6 bytes.

'!+OR"

Pruébalo en línea! ¡Prueba dos copias! ¡Prueba tres!

Explicación

Esta es solo la quine estándar de fisión . Resulta que funciona para este desafío, porque Fission tiene puntos de entrada explícitos en el programa. En particular, al duplicar el programa, agregamos otro Rque agrega otro átomo (puntero de instrucción). Como el código fuente es toroidal, el código efectivo que se está ejecutando no cambia de otra manera: para cada átomo, el código todavía se ve igual localmente. Sin embargo, los átomos se ejecutan en el paso de bloqueo, de modo que las cosas que imprimen se intercalan y obtenemos una copia adicional de cada carácter en la salida.

En aras de la integridad, solo reiteraré brevemente cómo funciona el programa en sí. Independientemente de si repetimos el programa o no (por ejemplo '!+OR"'!+OR"'!+OR"), cada átomo ve el siguiente código:

R"'!+OR"'!+O

El "modo de impresión se alterna cadena, por lo que el programa se inicia mediante la impresión '!+ORdirectamente a la salida estándar, que es toda la quine excepto la cita. Luego '!establece la masa del átomo en el código de caracteres !, lo +incrementa, lo que da "e Oimprime mientras destruye simultáneamente el átomo. El programa termina, porque no quedan átomos.

Martin Ender
fuente
11

Python 2.7, 377 310 304 194 191 bytes!

Este es mi primer golf, así que no esperaba que fuera demasiado bueno. Pero pensé que el concepto en la solución que se me ocurrió era algo divertido, así que lo publico de todos modos.

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()

De hecho, esto es una quine; Puedes probarlo aquí . Abusa del módulo de inspección bastante duro.

Si intentamos ejecutarlo con el mismo código fuente x2, también obtenemos la salida correcta; Puedes probar eso aquí . x3, x4, etc. todo funciona como se esperaba.

Sin disculpas con la explicación:

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
fuente
¿No es una trampa engañosa, ya que lee el código fuente de sus propias funciones inspect? (ver meta publicación relevante ). En PPCG tenemos definiciones específicas de lo que hace que una quine sea válida, y "leer la fuente" generalmente se considera una trampa.
FlipTack
@FlipTack No estoy seguro de que inspeccionar una función sea lo mismo que leer el código fuente. Quines en JavaScript y lenguajes basados ​​en pila hacen esto todo el tiempo.
Dennis
Okay :). He agregado resaltado de sintaxis para su publicación. ¡Buena idea usar hilos!
FlipTack
import threading,inspect as ipuede serimport threading as T,inspect as i
nedla2004
@FlipTack Vaya, gracias.
Calconym
3

CJam , 19 bytes

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

Pruébalo en línea!

Cómo funciona

{               }_~  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
fuente
Qué ... cómo ... tan rápido ... por favor explique el código, para que pueda enseñarme las formas de CJam.
clismique
@ Qwerp-Derp He agregado una explicación.
Dennis
3

RProgN , 66 bytes

Espacio en blanco significativo sea la muerte de mí

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

Explicado

[ "[ %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.

Dios mío, soy un monstruo ...

Pruébalo en línea!

Un taco
fuente
Además, aunque ~["[%q]F01+`0=`.{0m}R"]F01+`0=`.{0m}Ren general funciona bien, no es una solución válida, porque no hay forma de replicar el marcador ZSS.
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}

Sin golf:

$_ = '...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
}

Pruébalo en línea!

Joey Marianer
fuente
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);

Pruébelo en línea: una copia | dos copias | tres copias | cuatro copias, con verificación automática

Cómo funciona

Esto utiliza la línea estándar de Python: almacene el código que desea ejecutar en una variable (como una cadena); incluye algo de lógica en esa cadena para imprimirse, todo antes y todo después; luego ejecuta esa cadena.

El código que se ejecuta a través de la cadena s es el siguiente.

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

La primera línea importa incondicionalmente el módulo atexit , lo que nos permitirá registrar un controlador de salida. Intentar importar el mismo módulo varias veces no afecta el script de ninguna manera. Luego intenta incrementar la variable n , para realizar un seguimiento de cuántas copias del código fuente se ejecutaron.

La segunda línea se ejecuta solo si la primera contiene un error. Este será el caso en la primera iteración, ya que n todavía no está definido. En este caso, inicializamos n como 1 y registramos una lambda que realiza la magia real.

El manejador de salida registrado

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

se llamará justo antes de que finalice el programa. La lambda sí mismo crea la cadena "s=%r;exec(s);"%s- %rcrea una representación de cadena del argumento de la derecha ( s ), que incluye todo lo que entre las comillas simples y las propias cotizaciones - entonces itera sobre sus personajes. Para cada carácter c , simplemente imprimimos n copias de c . Pasar c*ncomo argumento nombrado enda printsignifica que no se agregará ningún salto de línea.

Dennis
fuente
1

CJam , 14 bytes

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

Pruébalo en línea!

Explicaciones

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