Scrivi il periodo più lungo iterando quine delimitato da 500 byte


16

Il tuo compito è quello di creare il periodo più lungo iterando quine , in cui la lunghezza di ciascun programma nella sequenza è limitata da 500 byte.

Cioè, se si ripetono i seguenti passaggi:

  1. Inizia con il tuo programma iniziale
  2. Esegui il programma corrente
  3. Torna al passaggio 2

Alla fine tornerai al tuo programma originale. Il numero di programmi nel ciclo è il tuo punteggio, che stai cercando di massimizzare.

Nessuno dei programmi può generare errori. Ogni programma deve essere eseguito allo stesso modo (ad es. Nessuna versione, implementazione, opzione del compilatore, piattaforma, ecc. Diverse (EDIT: Sì, qualsiasi stato esterno come quello di un generatore di numeri pseudo casuali è stato incluso nell'ultimo istruzione. Lo stato esterno deve essere "ripristinato" dopo ogni esecuzione. Se si utilizzano numeri casuali veri, si presume il caso peggiore.)

Ciò che separa questa sfida dal periodo più lungo che fa iterare il quine (diverso da 100 vs 500) è che ogni programma nel ciclo deve anche essere di 500 byte o meno. Ciò significa che il ciclo più lungo possibile è (256 ^ 501 - 1) / 255 o meno. Questo ovviamente è un numero elevato, ma non così grande in termini di codice necessario per il calcolo. Quindi la sfida consiste nell'utilizzare quante più possibilità (256 ^ 501 - 1) / 255 possibile, non una sfida di castori impegnata.

Ai programmi non è consentito accedere al proprio codice sorgente. Tuttavia, se lo si desidera, è consentito un programma vuoto (purché si rispettino le altre regole).

Dal momento che controllare i programmi manualmente sarebbe difficile, è possibile capire il punteggio usando metodi teorici. È necessario includere una spiegazione del punteggio e della correttezza con il programma. Se non riesci a capire il punteggio, puoi invece utilizzare un limite inferiore del numero di programmi nel ciclo come punteggio defacto. Puoi aggiornarlo quando trovi limiti inferiori migliori o se trovi il punteggio effettivo esatto.

Questa è , quindi il punteggio più alto vince!

EDIT: si consiglia di scrivere qual è il tuo punteggio in notazione scientifica, in modo che le risposte siano più facilmente comparabili. È perfettamente bene avere anche altre forme del punteggio, specialmente se sono più chiaramente collegate al tuo programma. Inoltre, i lettori sono incoraggiati a modificare le risposte precedenti per conformarsi a questo.


2
"il ciclo più lungo possibile è (256 ^ 501 - 1) / 255 o meno" --- questo non è necessariamente vero, il programma può passare attraverso lo stesso stato più volte prima di tornare all'originale se manipola un oggetto esterno ( come lo stato o il seme RNG)
JDL

2
@JDL che dovrebbe essere contro le regole, IMHO - se memorizza lo stato altrove rispetto al codice sorgente, allora non è un quine iterante corretto.
Nathaniel,

1
@Nathaniel Non lo classificherei come stato di archiviazione altrove, sta semplicemente usando i punti di ingresso che sono una parte valida del linguaggio di programmazione in cui è implementato. Probabilmente, tutto ciò che chiama un'altra funzione nel linguaggio di programmazione accede a stati che sono tenuti fuori il suo codice sorgente.
JDL

1
@JDL no, quelle sono cose diverse. Qualsiasi programma in qualsiasi lingua deve ovviamente fare affidamento su cose implementate al di fuori del codice sorgente, ma la memorizzazione dello stato al di fuori del codice sorgente è diversa. Ciò significherebbe che l'output del programma non è una funzione deterministica del suo codice sorgente, ma dipende invece da qualche altro contesto esterno che è stato modificato da precedenti esecuzioni. Ciò non dovrebbe essere consentito in una quine challenge, IMHO, e l'affermazione del PO sulla durata massima del ciclo indica che qui si intendeva vietare.
Nathaniel,

3
@JDL, ne sono certo, in un linguaggio deterministico il puntatore alle istruzioni memorizza lo stato solo durante l'esecuzione di un programma, e non tra invocazioni di esso. Il tuo esempio a 5 stati non è possibile se l'output del programma è una funzione deterministica della sua fonte.
Nathaniel,

Risposte:


12

Perl 6 , 1263988.86×10835 iterazioni

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

Provalo online!

Ciò scorre tutte le possibili combinazioni dei primi 126 byte di lunghezza 398 e inferiore (escluse le stringhe con byte NUL iniziali). Se vuoi vedere che ritorna effettivamente alla prima iterazione, puoi ridurre la lunghezza a 1 modificando il limite in questo modo .

Spiegazione:

Ogni iterazione incrementa la stringa, memorizzata nella forma base 126, quindi la converte in base 126. Lo fa fino a quando non raggiunge una stringa con lunghezza 399, quindi reimposta nuovamente la stringa per svuotarla nuovamente. Se hai problemi a concettualizzare il numero, immaginalo invece con dieci byte. A partire da 0, incrementa fino a 4 cifre 1000e ripristina. Sono 104-1 iterazioni (inclusa 0o stringa vuota nel caso del mio programma).

$!=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

1
Wow, l'hai fatto davvero in fretta, ho quasi finito con il mio, ma probabilmente lo
finirò

Questo calcolo suggerisce che hai superato il tuo punteggio stimato. Il numeratore indica quante stringhe di lunghezza 397 ci sono usando 126 simboli. (Ho dovuto distribuire la frazione nella somma poiché wolfram alpha si comportava in modo strano.)
PyRulez,

@PyRulez Penso che il mio numero sia corretto, dal momento che fondamentalmente sta iterando un numero 126 di base fino a 399 cifre ... Penso che la mia spiegazione fosse disattivata
Jo King,

@JoKing ah sì, penso che la spiegazione sia stata il problema. Hai modificato da 397 a 398, il che rende il tuo punteggio non più sopravvalutato. Potresti sottovalutarlo (dal momento che hai incluso solo stringhe di lunghezza esattamente 398 nel punteggio), ma va bene.
PyRulez,

2

Incantesimi runici , 64654 106 ; 122 387 -1 ≈ 2.638 × 10 807 iterazioni

"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]}@

Provalo online!

Avviso: viene visualizzato in modo errato, dovrebbe essere `` (0x80).

Anziché lo stack, utilizzare una stringa e gli operatori dello stack modificati con ͍per modificare una stringa anziché lo stack (vedere la revisione precedente). Pertanto, ogni carattere è limitato a 1 byte (intervallo 0-127, meno i caratteri problematici), ma con oltre 3 volte il numero di essi (a causa della minore elaborazione della piastra di caldaia dovuta al fatto che non è necessario saltare Unicode combinando caratteri, come oltre ad altri risparmi di byte) raggiunge un numero maggiore di iterazioni.

Se è consentita la codifica come un vero big endian (ovvero con valori di byte superiori a 127 senza interiezione di 0x00byte), è possibile ottenere 251 387 -1 ≈ 4.717 × 10 928 iterazioni. Tuttavia, la codifica latina di TIO impedisce questo, come notato da Erik the Outgolfer nella sua risposta Python 2. Dovrei verificare se funziona localmente prima di richiedere questo punteggio.

Dovrebbe essere in grado di sostituirlo f1+0Bcon '0B(c'è una 0x16non stampa lì), ma mi stava combattendo (le cose non volevano ramificare / saltare / tornare correttamente), quindi l'ho lasciato da solo. Ciò aumenterebbe la struttura del big endian da 387 a 388.


1

COM DOS, 49 byte, periodo 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                                                |.|

Assemblaggio originale per creare:

 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

Questo piccolo gioiello scrive la fase successiva su q.com anziché sullo standard output a causa di valori nulli e altre cose che il terminale non può gestire. La tecnica root quine equivale alla stringificazione e la sala payload viene utilizzata come contatore a 3608 bit. A causa del modo in cui funziona DOS, lo stato iniziale del contatore contiene detriti da qualsiasi cosa fosse in memoria prima della sua prima esecuzione.

L'input originale da 49 byte è irraggiungibile, quindi se si desidera ottenere un punteggio pari a 500 byte, andare avanti.


1

C # (compilatore interattivo Visual C #) , flag: /u:System.Numerics.BigIntegere/r:System.Numerics

Punteggio: 10 332

Grazie a JoKing che ha aumentato il mio punteggio da 10 255 * 2 - 1 ad ora!

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

Provalo online!

Spiegazione

Incrementa un BigInteger ad ogni iterazione, fino a quando la sua lunghezza diventa troppo grande, che in quel caso torniamo immediatamente al quine originale.

//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);

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

Si noti che esiste una nuova riga finale. Potrebbe essere rimosso sopra se l'evidenziatore della sintassi si fa strada.

Sfortunatamente, non è possibile eseguire questo programma in TIO, poiché è codificato in Latin-1.

Sopra, scontiene 219 0x01 byte. Dopo l'esecuzione del programma, la sua fonte viene stampata, fatta eccezione per una differenza: sè stata incrementata come un numero big-endian base-252, quindi il suo carattere più a sinistra è stato "incrementato" a 0x02. I byte 0x00, 0x22, 0x25 e 0x5C vengono evitati, quindi, se uno qualsiasi dei caratteri della stringa diventa uno di quelli dopo l'incremento, il carattere stesso viene nuovamente incrementato.

  • 0x00 (null): un file sorgente Python non può contenere caratteri null.
  • 0x22 ( "): esiste il pericolo che si formino tre byte 0x22 in una riga, ovvero """, o che l'ultimo carattere della stringa diventi" , quindi la stringa verrebbe chiusa prematuramente.
  • 0x25 ( %): printf simile formattazione stringa viene utilizzato prima del completamento dello scheletro quine, quindi una %non adiacente all'altro %in scauserà difficoltà. Sfortunatamente, non è possibile riordinare la formattazione per evitare questo avvertimento.
  • 0x5C ( \): esiste la possibilità che \sia usato come segno di escape nella stringa, anziché testualmente, quindi è evitato.

Pertanto, sono utilizzabili 252 su 256 byte. Se scontiene 219 0xFF ( ÿ) byte, viene semplicemente ripristinato a 219 0x01 byte, completando quindi il ciclo.

252219

252219=8067118401622543607173815381864126969021321378412714150085501148172081568355283332551767558738710128769977220628694979838777041634307806013053042518663967641130129748108465109552157004184441957823830340121790768004370530578658229253323149648902557120331892465175873053680188287802536817909195292338112618632542000472094347226540339409672851252596442228662174845397731175044304251123874046626291460659909127172435776359148724655575878680270692451120531744950544969860952702932354413767504109600742385916705785109741289800204288


1

2512262.1×10542

  • 251 39 rimosso dipendenzaText
  • 251 122 funzione di incremento golfizzata
  • 251 128 stringhe sorgente di prefisso e suffisso combinate
  • 251 188 ha rimosso la dipendenza daGast.GenLibTest

Presentato in formato xxd a causa di non stampabili / UTF-8 non valido:

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="

Provalo online!

Incrementa una stringa 226 byte attraverso tutti i valori di byte escluso \0, \n, \r, 'e \.

Il motivo per cui evitiamo questi personaggi è:

  • \0 fa arrabbiare il compilatore
  • \n e \r non può apparire negli elenchi
  • ' finirebbe la lista dei favoriti
  • \ potrebbe causare problemi se precede un personaggio sfuggente

Una volta che la stringa è tutta \377s, si avvolge attorno a tutte le \001s, dando il programma originale.


L'output (almeno su TIO) è il carattere con valore ordinale 128, ma composto dai due byte C2 80. È lo stesso del comportamento sul tuo computer locale?
Jo King,

1
@JoKing Oh, no, ricevo un singolo byte sulla mia macchina. L'output dei mangles TIO non è valido quando UTF-8 (e anche i file di input).
Οuroso

1
@JoKing Ho cambiato la risposta in un nuovo formato che rende possibile vedere il comportamento corretto su TIO.
Οuroso

0

Gol> <> , 70 byte, 39039000 iterazioni

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

Wow, è molto più basso di quanto pensassi sarebbe ... Il prossimo passo! Facendolo avere più iterazioni !!!

Provalo online!


non sembra cancellare nulla una volta che raggiunge 500, aggiunge
Jo King

Funziona davvero? Non riesco a far funzionare "incrementare l'ultimo carattere"
solo ASCII l'

@ ASCII-only Ora funziona, scusatemi prima, avevo incasinato una sezione mentre lavoravo per sistemare il tutto. Funziona ora, scusate l'inconveniente !!!
KrystosTheOverlord,

@JoKing Il byte NUL è il processo di eliminazione, ora il programma dovrebbe eliminare fino a quando non è quasi scomparso, quindi eliminare il NUL e incrementare l'ultimo carattere, se è un ~, quindi verrà convertito in un '#', tornando indietro alla normalità !!!
KrystosTheOverlord,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.