Hyper sobre quines

27

Inspirado en la hiperprogramación: N + N, N × N, N ^ N, todo en uno .
Gracias a @MartinEnder y @trichoplax por su ayuda en el sandbox.

Definiciones

Hiperquinas

Defina una hiperquina de orden n como un programa completo tipo quine o función P que satisfaga todas las reglas que se aplican a las quines adecuadas y, además, tiene la siguiente estructura.

P es la concatenación de grupos de caracteres que consisten en n copias del mismo carácter. Cuando se ejecuta P , la salida es la concatenación de los mismos grupos, aumentada por una copia más del carácter.

Ejemplos

  • En un lenguaje de programación hipotético donde el código fuente aabbccgenera la salida aaabbbccc, este programa constituye una hiperquina del orden 2 .

  • La definición no requiere que los caracteres de diferentes grupos sean diferentes.

    Si el código fuente aabbccgenera la salida aaaabbbbcccc, el programa es una hiperquina del orden 1 ; El código fuente consta de seis grupos de un solo carácter, la salida de seis pares de caracteres.

  • En GS2 , la impresora vacíos del programa \n, y el programa \nimprime \n\n. Sin embargo, ni \ntampoco \n\nson hiperquinas, ya que no satisfacen todas las propiedades de quinas adecuadas ; ninguna parte del código fuente codifica una parte diferente de la salida.

Cadenas de hiperquina

Defina una cadena hiperquina de longitud n como una secuencia finita de n programas completos o n funciones
(P 1 , ..., P n ) que satisfaga las siguientes restricciones.

  1. Las salidas de P 1 , ..., P n-1 son P 2 , ..., P n , respectivamente.

  2. P 1 , ..., P n son hiperquinas.

  3. Los órdenes de P 1 , ..., P n forman una secuencia estrictamente creciente de enteros adyacentes .

Finalmente, defina una cadena de hiperquina infinita como una secuencia infinita de programas o funciones completas (P 1 , P 2 , ...) de tal manera que cada intervalo inicial (P 1 , ..., P n ) constituya una cadena de cadena de hiperquina n .

Ejemplos

  • En un lenguaje de programación hipotético donde el código fuente aabbccgenera la salida aaabbbccc, que, a su vez, genera la salida aaaabbbbcccc, el par ( aabbcc, aaabbbccc) constituye una cadena hiperquina de longitud 2 .

    Tenga en cuenta que aaaabbbbcccc, la salida de la última hiperquina en la cadena, no tiene que producir una salida específica; ni siquiera tiene que ser un código fuente válido.

  • Continuando con el ejemplo anterior, si aaaabbbbccccgenera la salida aaaaabbbbbccccc, el triplete ( aabbcc, aaabbbccc, aaaabbbbcccc) que constituye una cadena hyperquine de longitud 3 .

    Si este patrón continúa para siempre, la secuencia ( aabbcc, aaabbbccc, aaaabbbbcccc, ...) constituye una cadena infinita hyperquine.

  • El par de programas ( abc, aabbcc) con salidas ( aabbcc, aaaabbbbcccc) no es una cadena de hiperquina, ya que los órdenes de las hiperquinas son ambos 1 , por lo que no forman una secuencia estrictamente creciente.

  • El par de programas ( aabbcc, aaaabbbbcccc) con salidas ( aaaabbbbcccc, aaaaabbbbbccccc) no es una cadena de hiperquina, ya que los órdenes de las hiperquinas son 1 y 4 , por lo que no forman una secuencia de enteros adyacentes.

Reglas

Tarea

En un lenguaje de programación de su elección, escriba una cadena de hiperquina no trivial, es decir, una cadena que conste de al menos 2 hiperquinas.

Como de costumbre, sus programas no pueden tomar ninguna entrada o acceder a su propio código fuente de ninguna forma.

Si su intérprete imprime una nueva línea implícita, sus hiperquines tienen que dar cuenta de esto.

Se aplican todas las lagunas estándar , especialmente las relacionadas con quines.

Tanteo

La cadena de hiperquina más larga gana. Si dos o más envíos están vinculados, el envío entre estos que comienza con la hiperquina más corta (medida en caracteres ) gana. Como de costumbre, el tiempo de publicación es el desempate final.


Debe usar la misma codificación de caracteres para el código fuente, la salida, el recuento de caracteres y la ejecución. Por ejemplo, el programa Python noprint 42 es un envío UTF-32 de 2 caracteres, ya que el intérprete trata cada byte como un solo carácter. Si su idioma de elección no está basado en caracteres, trate todos los bytes individuales como caracteres.

Dennis
fuente
3
Bien, quizás el desafío de Helka no fue imposible, pero seguramente esto es: D
Beta Decay
1
@BetaDecay ¿Es realmente? :)
Martin Ender

Respuestas:

10

Befunge-98 , orden infinito, 54 52 38 36 bytes

Segundo enfoque: orden infinito, 36 bytes

Este programa realmente se rompería en la 34a hiperquina ya que el valor ASCII de "interrumpiría la interpretación de la cadena (y en 59, ;), pero compensamos el almacenamiento de ese valor en una posición que nunca se ejecutará (es decir, en (0, 1)lugar de (0, 0)).

1+::0*x01pn'!1+:#jr;,kg10@k!:kg10;#"

Pruébelo en línea: 1 , 2 , 10 , 34 , 42

Explicación

INSTRUCTIONS  STACK (PYTHON PSEUDOCODE)           EXPLANATION
1+            [n]                                 Push n many 1s onto the stack, then sum them up
::            [n]*(at least 3)                    Duplicate that sum at least twice
0*            [n]*(at least 2)+[0]                Push a whole lot of zeros, then multiply them all together
x             [n]*(at least 1)                    Pop a vector off the stack (n, 0) and set the IP delta to that; now the IP is only executing every nth character
01p           [n]*(at least 1)                    Place n in the program at coordinates (0, 1); this is just for storage
n             []                                  Clear the stack
'!1+          ['"']                               '!' is character 33; one less than 34, or '"'
:#jr          ['"']                               We duplicate the 34 (all we care is that it's a rather large number), then turn around and skip that many spaces
                                                  The IP, having jumped 34*n instructions to the left, is now way in the negatives
                                                  Execution resumes on the other side of the program (the following instructions have been reversed for readability
"             [the program of order 1]            The quote-at-the-end-of-the-program is a common trick for one-liner Befunge quines
#; ... ;                                          Jumps into a loop (when the IP hits one semicolon it skips to the next, restarting the loop)
01gk:         [(rest of string), char*(n+2)]      This duplicates the letter n+1 times*, leaving n+2 copies on the stack
!k@                                                If the number on the top of the stack is zero (i.e. we are printing), it will execute '@',
                                                  ending the program; otherwise, it will NOT execute '@' and will instead continue normally
                                                  Vague* 'k' instruction FTW
10gk,                                             If we aren't done yet, print the character n+1 times* (and restart the loop)

* 'k' is a very strange instruction. It pops a number off the stack; if the number is zero, it skips the command in front of it. If the number is greater than zero,
  it will execute the instruction that many times PLUS ONE. This is actually strangely advantageous in this program.

Primer enfoque: orden 34, 52 bytes (utiliza introspección, por lo que técnicamente no es legal)

Por la razón en la publicación anterior, este programa se rompería en el orden 34 (aunque no lo he probado).

1+::0*x:00p'1\k:00gk,1#;:00g*0g00gk:$00gk,1+:'4-!k@;

Pruébalo en línea!

Hactar
fuente
2
Si bien el resultado parece ser correcto y esto es ciertamente impresionante, no estoy convencido de que se pueda usar una quine adecuadag , que parece leer directamente el código fuente del programa. Dicho esto, apenas soy un experto en Befunge, por lo que podría estar malentendido algo.
Dennis
Estoy usando gpara dos propósitos aquí: almacenar datos y leer el código fuente. El segundo puede ser un poco incompleto, a pesar de que esolangs.org/wiki/Befunge#Quine también tiene un ejemplo gpara leer el código fuente. Mientras tanto, veré si puedo crear una versión que no use ninguna introspección.
Hactar
Sabía que esto tenía que ser posible en Befunge, pero no tenía idea de cómo. Gracias por mostrarme +1
ETHproductions
10

> <> , orden infinito, 178 bytes

El programa contiene un salto de línea final.

^
.
*
&
:
&
+
*
2
b
*
*
6
9
$
0
)
*
4
8
:
~
.
*
&
:
&
+
*
2
b
*
*
2
b
$
0
)
i
:
-
1
o
a
&
:
&
o
~
.
*
&
:
&
+
*
7
7
*
*
4
6
$
0
)
0
:
-
1
$
o
:
$
&
:
&
&
,
*
8
b
-
1
l
}
*
3
d
'

Pruébelo en línea: 1 , 2 , 3 , 10 (el último tarda un tiempo en ejecutarse).

Script de retina para generar fuente desde un programa lineal.

Explicación

La idea principal es girar la quine vertical, para que el flujo de control real no se vea afectado por la repetición. Por ejemplo, la segunda hiper quina comienza como:

^^

..

**

Como solo nos estamos moviendo a través de la primera columna, no tenemos que preocuparnos por los caracteres repetidos. Además, cuando empujamos la mayoría del código como una cadena con ', esto empujará un espacio para cada línea vacía, lo que nos da una manera de determinar el número de repeticiones. Dicho esto, hay algunas limitaciones debido a estas líneas vacías:

  • No podemos usar "para empujar grandes números como códigos de caracteres en la parte principal de la línea, porque esto empujaría 32s adicionales que no queremos.
  • No podemos usar ?o !porque solo omiten el siguiente carácter, que sería un espacio en ese caso (por lo que en realidad no omitirían el siguiente comando).

Por lo tanto, todo el flujo de control se realiza con saltos explícitos (básicamente 2D), cuyos desplazamientos reales necesitamos calcular en función del número de repeticiones.

Así que echemos un vistazo al código real. Comenzamos por ^lo que el código se ejecuta de abajo hacia arriba. Para una lectura más fácil, escribamos el código real en orden de ejecución (y descartemos ^porque nunca se vuelve a ejecutar):

'd3*}l1-b8*,&&:&$:o$1-:0)0$64**77*+&:&*.~o&:&ao1-:i)0$b2**b2*+&:&*.~:84*)0$96**b2*+&:&*.

Esta 'es la técnica de quining estándar para> <> (y Befunge, supongo). Cambia al modo de cadena, lo que significa que los caracteres encontrados se insertan en la pila hasta que 'se encuentra el siguiente . Las líneas vacías se rellenan implícitamente con espacios, por lo que obtenemos todos los espacios intermedios. Las líneas vacías al final del programa se ignoran. Entonces, después de que la IP se ajusta y golpea 'nuevamente, tenemos la primera columna del programa en la pila, excepto la 'propia.

Veamos cómo usamos esto para imprimir todo el programa.

d3*}    Put a 36 (the ') at the bottom of the stack. Now the stack holds
        a representation of the entire first column.
l1-     Push the depth of the stack, minus (so minus to ').
b8*,    Divide by 88. The original program has 89 lines. If we divide the 
        depth of the stack (minus 1) by 88, we get the order of the current
        hyperquine (due to all the spaces we've pushed).
&       Store the order of the hyperquine in the register.
        Begin of main loop:
&:&       Push a copy of the register onto the stack. Call that N.
          Begin of line-printing loop:
$:o$        Print a copy of the top character on the stack.
1-          Decrement N.
:0)         Check whether it's still positive (gives 0 or 1).
0$          Put a 0 underneath. This will be the x-coordinate of a jump.
64**        Multiply the conditional by 24. This is the number of commands
            in this inner loop.
77*+        Add this to 49, the offset of the end of the loop.
            The result is line we want to jump to in the order-1 hyperquine.
&:&*        Multiply by the order of the quine (so that we jump further on
            higher quine orders).
.         Jump. If N isn't zero yet, this repeats the inner loop. Otherwise
          we continue right here.
~         Discard N (now 0).
o         Output one last copy of the top character on the stack.
&:&       Push a copy of the register onto the stack. Call that N.
          Begin of linefeed-printing loop:
ao          Print a linefeed.
1-          Decrement N.
:i)         Check whether it's still non-negative (gives 0 or 1).
            The next bit is essentially the same loop structure as above,
            but with loop length 22 and offset 22:
0$
b2**
b2*+
&:&*
.         Jump. If N isn't -1 yet, this repeats the inner loop. Otherwise
          we continue right here.
          Begin of space-clearing loop:
~           Discard the top of the stack. On the first iteration this is the
            -1 from the previous loop. Afterwards, it's one of the spaces
            representing an empty line.
:84*)       Check if the top of the stack is a space.
            And another loop conditional. This one works the other way round:
            the difference is 54, which is the distance between the beginning
            of this loop and the main loop. The offset is the beginning
            of this loop, at 22 as above.
0$
96**
b2*+
&:&*
.         Jump. If the top of the stack is still a space this repeats the 
          inner loop. Otherwise we continue from the top of the main loop.

El programa termina cuando la pila está vacía y el primer bucle interno no puede imprimir otro carácter.

Martin Ender
fuente