Escriba el período más largo iterando quine delimitado por 500 bytes

16

Su trabajo es crear la quine iterativa de período más largo , donde la longitud de cada programa en la secuencia está limitada por 500 bytes.

Es decir, si repite los siguientes pasos:

  1. Comience con su programa inicial
  2. Ejecuta el programa actual
  3. Regrese al paso 2

Eventualmente volverá a su programa original. El número de programas en el ciclo es su puntaje, que está tratando de maximizar.

Ninguno de los programas puede generar errores. Cada programa también debe ejecutarse de la misma manera (por ejemplo, no hay diferentes versiones, implementaciones, opciones de compilación, plataformas, etc.) (EDITAR: Sí, cualquier estado externo como el de un generador de números pseudoaleatorios se incluyó en el último declaración. El estado externo debe "restablecerse" después de cada ejecución. Si utiliza números aleatorios verdaderos, se supone el peor de los casos).

Lo que separa este desafío del Quine iterativo de período más largo (que no sea 100 vs 500) es que cada programa en el ciclo también debe tener 500 bytes o menos. Esto significa que el ciclo más largo posible es (256 ^ 501 - 1) / 255 o menos. Eso, por supuesto, es un gran número, pero no tan grande en términos de cuánto código se necesita para calcular. Por lo tanto, el desafío consiste en utilizar tantas posibilidades (256 ^ 501 - 1) / 255 como sea posible, no un desafío de castores ocupados.

Los programas no pueden acceder a su propio código fuente. Sin embargo, se permite un programa vacío si lo desea (siempre y cuando siga las otras reglas).

Dado que verificar los programas manualmente sería difícil, puede calcular el puntaje utilizando métodos teóricos. Debe incluir una explicación del puntaje y la corrección con su programa. Si no puede calcular el puntaje, puede utilizar un límite inferior del número de programas en el ciclo como puntaje de facto. Puede actualizar esto a medida que encuentre mejores límites inferiores, o si encuentra el puntaje real exacto.

Este es , por lo que gana la puntuación más alta.

EDITAR: Se recomienda que escriba cuál es su puntaje en notación científica, para que las respuestas sean más fácilmente comparables. Está perfectamente bien tener otras formas de puntuación, especialmente si están más claramente conectadas a su programa. Además, se alienta a los lectores a editar respuestas anteriores para cumplir con esto.

PyRulez
fuente
2
"el ciclo más largo posible es (256 ^ 501 - 1) / 255 o menos" --- esto no es necesariamente cierto, el programa puede pasar por el mismo estado varias veces antes de volver al original si manipula un objeto externo ( como el estado RNG o semilla)
JDL
2
@JDL que debería estar en contra de las reglas, en mi humilde opinión: si almacena el estado en otro lugar que no sea el código fuente, entonces no es una quine iterativa adecuada.
Nathaniel
1
@Nathaniel No lo categorizaría como estado de almacenamiento en otro lugar, simplemente está usando puntos de entrada que son una parte válida del lenguaje de programación en el que se implementa. Posiblemente, cualquier cosa que llame a otra función en el lenguaje de programación es acceder a estados que se mantienen fuera Su propio código fuente.
JDL
1
@JDL no, esas son cosas diferentes. Cualquier programa en cualquier idioma obviamente tiene que depender de cosas que se implementan fuera del código fuente, pero el estado de almacenamiento fuera del código fuente es diferente. Eso significaría que la salida del programa no es una función determinista de su código fuente, sino que depende de algún otro contexto externo que haya sido modificado por ejecuciones anteriores. Eso no debería permitirse en un desafío de quine, en mi humilde opinión, y la declaración del OP sobre la duración máxima del ciclo indica que estaba destinado a ser rechazado aquí.
Nathaniel
3
@JDL, como estoy seguro de que sabe, en un lenguaje determinista el puntero de instrucción solo almacena el estado durante la ejecución de un programa, y ​​no entre invocaciones de este. Su ejemplo de 5 estados no es posible si la salida del programa es una función determinista de su fuente.
Nathaniel

Respuestas:

12

Perl 6 , 1263988.86×10835 iteraciones

$!=Q~~;<say "\$!=Q~{chrs(my@a=[R,] polymod :126[$!.ords]+1: 126 xx*)x?(@a-399)}~;<$_>~~.EVAL">~~.EVAL

Pruébalo en línea!

Esto itera a través de todas las combinaciones posibles de los primeros 126 bytes de longitud 398 y menos (excluyendo cadenas con bytes NUL iniciales). Si desea ver que realmente vuelve a la primera iteración, puede reducir la longitud a 1 cambiando el límite de esta manera .

Explicación:

Cada iteración incrementa la cadena, almacenada en forma de base 126, y luego la convierte de nuevo en base 126. Hace esto hasta que alcanza una cadena con longitud 399, y luego restablece la cadena para vaciarla nuevamente. Si tiene problemas para conceptualizar el número, imagínelo con diez bytes. A partir de 0, incremente hasta 4 dígitos 1000y reinicie. Esto es 104 4-1 iteraciones (incluyendo 0o cadena vacía en el caso de mi programa).

$!=Q~~;         # Start with an empty string
< ... >~~.EVAL  # Set a string to $_ and EVAL it
  say "\$!=Q~{...}~;<$_>~~.EVAL"   # Print the program with the string replaced by
                       :126[$!.ords]   # The string converted from base 126
                                    +1 # Incremented
          [R,] polymod                : 126 xx*  # Back to base 126
chrs(                                )  # Back to a string
     my@a=                            x?(@a-399)  # Only if it isn't 399 characters
Jo King
fuente
1
Wow, lo hiciste muy rápido, casi termino con el mío, pero probablemente lo terminaré mañana (el mío estará en Gol> <>)
KrystosTheOverlord
Este cálculo sugiere que sobrepasaste tu puntaje. El numerador es cuántas cadenas de longitud 397 hay usando 126 símbolos. (Tuve que distribuir la fracción en la suma ya que Wolfram Alpha estaba actuando raro.)
PyRulez
@PyRulez Creo que mi número es correcto, ya que básicamente está iterando un número base 126 de hasta 399 dígitos ... Creo que mi explicación estaba apagada
Jo King
@JoKing ah sí, creo que la explicación fue el problema. Cambiaste 397 a 398, lo que hace que tu puntuación ya no sea una sobreestimación. Es posible que lo esté subestimando (ya que solo incluyó cadenas de longitud exactamente 398 en el puntaje), pero está bien.
PyRulez
2

Encantamientos rúnicos , 64654 106 ; 122 387 -1 ≈ 2.638 × 10 807 iteraciones

"3X4+kSq'ƃZ,r{1?{1[:1Z%1+:a=+:d=+:3X4+=+:6X2+=+:'€(c*?~1-1kq}͍f1+0Bl1=6*?S1-Skql͗2=4*?{͍]}B͍l1=6*?kS1-Sq]}@

Pruébalo en línea!

Alerta: se muestra incorrectamente, debería ser `` (0x80).

En lugar de la pila, use una cadena y los operadores de pila modificados con ͍ para modificar una cadena en lugar de la pila (ver revisión previa). Como tal, cada carácter está limitado a 1 byte (rango de 0-127, menos los caracteres problemáticos), pero con más de 3 veces más (debido a que hay menos repetitivo de procesamiento debido a que no tiene que omitir los caracteres de combinación Unicode, como así como otros ahorros de bytes) logra un mayor número de iteraciones.

Si se permite la codificación como un verdadero big endian (es decir, tener valores de byte superiores a 127 sin interponer 0x00bytes), esto puede lograr 251 387 -1 ≈ 4.717 × 10 928 iteraciones. Sin embargo, la codificación latina de TIO evita esto, como lo señaló Erik the Outgolfer en su respuesta de Python 2. Necesitaría verificar si funciona localmente antes de reclamar este puntaje.

Debería poder reemplazar f1+0Bcon '0B(hay una impronta 0x16allí), pero estaba luchando contra mí (las cosas no querían ramificarse / saltar / regresar correctamente), así que lo dejé solo. Esto elevaría la estructura big-endian de 387 a 388.

Draco18s ya no confía en SE
fuente
1

DOS COM, 49 bytes, período 2 ^ 3608

00000000  be 31 01 89 f7 b9 f4 02  f9 ac 14 00 aa 39 ce 72  |.1...........9.r|
00000010  f8 31 c9 b4 3c ba 2b 01  cd 21 89 c3 b4 40 b9 f4  |.1..<.+..!...@..|
00000020  01 ba 00 01 cd 21 b4 3e  cd 21 c3 71 2e 63 6f 6d  |.....!.>.!.q.com|
00000030  00                                                |.|

Ensamblaje original para crear:

 BITS 16
 ORG 0100h
   mov si, l
   mov di, si
   mov cx, 500 + 0100h
   stc
n: lodsb
   adc al, 0
   stosb
   cmp si, cx
   jb n
   xor cx, cx
   mov ah, 3ch
   mov dx, f
   int 21h
   mov bx, ax
   mov ah, 40h
   mov cx, 500
   mov dx, 0100h
   int 21h
   mov ah, 3eh
   int 21h
   ret
f: db "q.com", 0
l: db 0

Esta pequeña joya escribe la siguiente fase en q.com en lugar de la salida estándar debido a nulos y otras cosas que el terminal no puede manejar. La técnica de quine de raíz es equivalente a la stringificación y la sala de carga se utiliza como un contador de 3608 bits. Debido a la forma en que funciona DOS, el estado inicial del contador contiene restos de lo que haya en la memoria antes de su primera ejecución.

La entrada original de 49 bytes es inalcanzable, por lo que si desea anotar esto como 500 bytes, continúe.

Joshua
fuente
1

C # (compilador interactivo de Visual C #) , marcas: /u:System.Numerics.BigIntegery/r:System.Numerics

Puntuación: 10 332

¡Gracias a JoKing que aumentó mi puntaje de 10 255 * 2 - 1 hasta ahora!

var i=Parse("0");var s="var i=Parse({0}{2}{0});var s={0}{1}{0};Write(s,(char)34,s,(++i).ToString().Length<333?i:0);";Write(s,(char)34,s,(++i).ToString().Length<333?i:0);

Pruébalo en línea!

Explicación

Incrementa un BigInteger cada iteración, hasta que su longitud se vuelve demasiado grande, lo que en ese caso volvemos instantáneamente a la quine original.

//The BigInteger that will be incremented
var i=Parse("0");
//The string that encodes the quine
var s="var i=Parse({0}{2}{0});var s={0}{1}{0};Write(s,(char)34,s,(++i).ToString().Length<333?i:0);";
//Print out the string, with every {0} replaced with quotes and the {1} replaced with the original string
Write(s,(char)34,s,
//And the {2} is replaced to the BigInteger+1 if the BigInteger wouldn't be too long, else 0
(++i).ToString().Length<333?i:0);
Encarnación de la ignorancia
fuente
1

252219

#coding=L1
s=""""""
for i in range(220-len(s.lstrip("ÿ")))[:219]:s=s[:i]+chr(ord(s[i])%255-~(s[i]in"!$&"))+s[i+1:]
S='#coding=L1\ns="""%s"""\nfor i in range(220-len(s.lstrip("\xff")))[:219]:s=s[:i]+chr(ord(s[i])%%%%255-~(s[i]in"!$&"))+s[i+1:]\nS=%%r;print S%%%%s%%%%S';print S%s%S

Tenga en cuenta que hay una nueva línea final. Podría eliminarse arriba si el resaltador de sintaxis se abre paso.

Desafortunadamente, no puede ejecutar este programa en TIO, ya que está codificado en Latin-1.

Arriba, scontiene 219 0x01 bytes. Después de que se ejecuta el programa, se imprime su fuente, excepto por una diferencia: sse ha incrementado como un número big-endian base-252, por lo que su carácter más a la izquierda se ha "incrementado" a 0x02. Se evitan los bytes 0x00, 0x22, 0x25 y 0x5C, por lo tanto, si algún carácter de la cadena se convierte en uno de esos después del incremento, el carácter en sí mismo se incrementa nuevamente.

  • 0x00 (nulo): un archivo fuente de Python no puede contener caracteres nulos.
  • 0x22 ( "): existe el peligro de que se formen tres bytes 0x22 en una fila, es decir """, o que el último carácter de la cadena se convierta" , por lo que la cadena se cerraría prematuramente.
  • 0x25 ( %): printf-como formato de cadenas se usa antes de la finalización del esqueleto quine, por lo que un %no adyacente a otra %en scausará problemas. Desafortunadamente, no es posible reordenar el formato para evitar esta advertencia.
  • 0x5C ( \): existe la posibilidad de que \se use como una marca de escape en la cadena, en lugar de textualmente, por lo que se evita.

Por lo tanto, 252 de 256 bytes son utilizables. Si scontiene 219 0xFF ( ÿ) bytes, simplemente se revierte a 219 0x01 bytes, completando así el ciclo.

252219

252219=8067118401622543607173815381864126969021321378412714150085501148172081568355283332551767558738710128769977220628694979838777041634307806013053042518663967641130129748108465109552157004184441957823830340121790768004370530578658229253323149648902557120331892465175873053680188287802536817909195292338112618632542000472094347226540339409672851252596442228662174845397731175044304251123874046626291460659909127172435776359148724655575878680270692451120531744950544969860952702932354413767504109600742385916705785109741289800204288

Erik el Outgolfer
fuente
1

limpia ,2512262.1×10542

  • 251 39 elimina la dependencia deText
  • 251 122 golfed función incrementar
  • 251 128 cadenas de fuente combinadas de prefijo y sufijo
  • 251 188 se eliminó la dependencia deGast.GenLibTest

Presentado en formato xxd debido a UTF-8 no imprimibles / no válidos:

00000000: 6d6f 6475 6c65 2071 3b69 6d70 6f72 7420  module q;import 
00000010: 5374 6445 6e76 3b53 7461 7274 3d28 7325  StdEnv;Start=(s%
00000020: 2830 2c34 3129 2c3f 5b27 0101 0101 0101  (0,41),?['......
00000030: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000040: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000050: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000060: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000070: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000080: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000090: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000a0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000b0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000c0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000d0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000e0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000f0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000100: 0101 0101 0101 0101 0101 0101 275d 2c73  ............'],s
00000110: 2528 3432 2c39 3939 292c 712c 732c 7129  %(42,999),q,s,q)
00000120: 3b71 3d69 6e63 2721 273b 3f5b 683a 745d  ;q=inc'!';?[h:t]
00000130: 2363 3d68 2b69 6628 616e 7928 283d 3d29  #c=h+if(any((==)
00000140: 6829 5b27 ff09 0c26 5b27 5d29 2702 2727  h)['...&['])'.''
00000150: 0127 3d5b 633a 6966 2863 3e68 2969 643f  .'=[c:if(c>h)id?
00000160: 745d 3b3f 653d 653b 733d 226d 6f64 756c  t];?e=e;s="modul
00000170: 6520 713b 696d 706f 7274 2053 7464 456e  e q;import StdEn
00000180: 763b 5374 6172 743d 2873 2528 302c 3431  v;Start=(s%(0,41
00000190: 292c 3f5b 2727 5d2c 7325 2834 322c 3939  ),?[''],s%(42,99
000001a0: 3929 2c71 2c73 2c71 293b 713d 696e 6327  9),q,s,q);q=inc'
000001b0: 2127 3b3f 5b68 3a74 5d23 633d 682b 6966  !';?[h:t]#c=h+if
000001c0: 2861 6e79 2828 3d3d 2968 295b 27ff 090c  (any((==)h)['...
000001d0: 265b 275d 2927 0227 2701 273d 5b63 3a69  &['])'.''.'=[c:i
000001e0: 6628 633e 6829 6964 3f74 5d3b 3f65 3d65  f(c>h)id?t];?e=e
000001f0: 3b73 3d22                                ;s="

Pruébalo en línea!

Incrementos de una cadena de 226 bytes a través de todos los valores de bytes excluyendo \0, \n, \r, 'y\ .

La razón por la que evitamos estos caracteres es:

  • \0 hace enojar al compilador
  • \ny \rno puede aparecer en las listas
  • ' terminaría el charlist
  • \ podría causar problemas si se trata de un personaje escapable

Una vez que la cadena es todo \377s, se ajusta a todos los \001s, dando el programa original.

Οurous
fuente
La salida (al menos en TIO) es el carácter con valor ordinal 128, pero compuesto por los dos bytes C2 80. ¿Es esto lo mismo que el comportamiento en su máquina local?
Jo King
1
@JoKing Oh, no, obtengo un solo byte en mi máquina. TIO manipula la salida cuando no es válida UTF-8 (y los archivos de entrada también).
Οurous
1
@JoKing He cambiado la respuesta a un nuevo formato que hace posible ver el comportamiento correcto en TIO.
Οurous
0

Gol> <> , 70 bytes, 39039000 iteraciones

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||lPaa*5*=?1:1=Q$~$~|:1)lPaa*5*(Q?:|r2ssH##

Wow, eso es mucho más bajo de lo que pensé que sería ... ¡Siguiente paso! Haciéndolo tener más iteraciones !!!

Pruébalo en línea!

KrystosTheOverlord
fuente
no parece eliminar nada una vez que alcanza 500, solo agrega un byte NUL
Jo King
¿Esto incluso funciona? No puedo hacer que funcione el "incremento del último carácter"
solo ASCII
@ Solo ASCII Ahora esto funciona, perdón por lo de antes, había estropeado una sección mientras trabajaba en arreglar todo. Funciona ahora, disculpe las molestias !!!
KrystosTheOverlord
@JoKing El byte NUL es el proceso de eliminación, ahora el programa debería eliminarse hasta que casi se haya acabado, luego eliminar el NUL e incrementar el último carácter, si es un ~, se convertirá en un '#', regresando a la normalidad !!!
KrystosTheOverlord