Il periodo più lungo che ripetono le quine


10

Come sappiamo, un quine è un programma che genera il proprio codice sorgente. Tuttavia, è anche possibile scrivere un programma che genera un altro programma diverso, che restituisce nuovamente il primo programma. Ad esempio, il programma Python 2

x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3

eseguirà, quando eseguito, il seguente testo:

print """x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3"""

Quando eseguito come programma Python, questo restituirà nuovamente il codice originale. Questo si chiama quine iterante . Poiché è necessario eseguirlo due volte per ripristinare il codice originale, si dice che ha periodo 2 . Ma ovviamente sono possibili periodi molto più alti.

La tua sfida è quella di scrivere un quine iterante con il più lungo periodo possibile, in 100 byte o meno , nella lingua che preferisci . (Nota che il mio esempio sopra non si adatta a questa specifica, in quanto è di 119 byte, inclusa la nuova riga finale.)

Si prega di notare le seguenti regole e chiarimenti:

  • Si applicano le consuete regole di quine, ovvero il tuo programma non può usare le funzionalità del linguaggio che gli consentirebbero di accedere direttamente al proprio codice sorgente.
  • Gli output iterati devono infine ritornare esattamente al tuo codice originale e devi includere una dimostrazione o una prova che lo farà.
  • Devi anche includere una spiegazione del perché il ciclo è lungo quanto dici. Questo non deve essere al livello di una prova matematica, ma dovrebbe essere convincente per qualcuno che abbia familiarità con la tua lingua. (Questa regola è qui perché mi aspetto che alcune delle risposte coinvolgano numeri molto, molto grandi.)
  • Va bene dire qualcosa come "almeno 1.000.000 di iterazioni" piuttosto che fornire il numero esatto, purché si possa dimostrare che è almeno così lungo. In questo caso, il tuo punteggio sarebbe 1.000.000. Altrimenti, il tuo punteggio è il periodo del tuo quine.
  • Il limite di 100 byte si applica solo al tuo programma iniziale: i programmi che emette possono essere più lunghi, anche se ovviamente dovranno tornare a 100 byte per produrre il tuo codice originale.
  • Puoi presumere che la tua macchina abbia RAM infinita e runtime infinito, ma non puoi assumere tipi di dati di precisione illimitati (come numeri interi) se la tua lingua non li ha. È possibile supporre non c'è limite alla lunghezza di inserire il parser in grado di gestire.
  • Vince il punteggio più alto.

Nota: esiste una sfida esistente chiamata Quit Whining; Inizia il quining che comporta anche l'iterazione di quines. Tuttavia, oltre ad essere basati sullo stesso concetto, si tratta di tipi di sfida completamente diversi. L'altro è il golf del codice, mentre questo è (intenzionalmente!) Un vero problema di castori sotto mentite spoglie. Le tecniche necessarie per produrre una buona risposta a questa domanda sono probabilmente molto diverse da quelle necessarie per rispondere all'altra domanda, e questo è molto legato alla progettazione.


1
@LeakyNun Non so se sei stato tu o una mod a eliminare la tua risposta, ma forse se ti spiego cosa non va in questo, capirai perché questo non è un duplicato. Questa domanda specifica un limite di 100 byte sulla lunghezza della sorgente, quindi in realtà non puoi andare "alto quanto vuoi" usando quel metodo. Questo è il punto centrale di questa domanda. Per rispondere, ciò che dovresti fare è pubblicare la versione più lunga che si adatta a 100 caratteri e dire qual è il suo periodo. Quello che hai pubblicato sarebbe un buon primo tentativo ma è molto improbabile che sia il vincitore.
Nathaniel,

1
@Dave la sfida è proprio quella di specificare un numero elevato in un piccolo numero di byte, sì. Questo è l'intero principio attorno al quale è stato progettato. La domanda è: 3 ^^^ 3 è il numero più alto che puoi specificare in 100 byte nella tua lingua o ce n'è uno più grande? Questa è la sfida. È il nocciolo di esso. È quello che volevo vedere fare la gente. È super, super frustrante averlo chiuso sulla base di una superficiale somiglianza con una sfida che non ha nulla di questa struttura.
Nathaniel,

1
@Dave (secondo commento) ma se sei intelligente, non devi essere affatto limitato dalla precisione della macchina. Mi aspetto che le risposte competitive abbiano un periodo molto più lungo di 2 ^ (2 ^ 64).
Nathaniel,

3
Preferiresti che fosse chiuso come duplicato di codegolf.stackexchange.com/q/18028/194 ?
Peter Taylor,

1
@PeterTaylor è un tema molto più vicino, ma è ancora una sfida molto diversa: stampare un numero è abbastanza diverso dal fare qualcosa un gran numero di volte. Preferirei ovviamente che non fosse affatto chiuso.
Nathaniel,

Risposte:


10

PHP, periodo 2.100.000.000

Chi avrebbe mai pensato che ciò fosse possibile in PHP ?! :-)

Questo è in realtà il mio primo quine in assoluto ed è lungo 99 byte:

<?$i=1;$i*=21e8>$i;printf($a='<?$i=%d;$i*=21e8>$i;printf($a=%c%s%c,++$i,39,$a,39);',++$i,39,$a,39);

Sebbene PHP supporti numeri maggiori rispetto 2 * 10^8al passaggio da integera double, l'incremento non funziona più (porta a un ciclo infinito) e non ho trovato un'altra soluzione che si adatti ai 100 byte. Ancora.

La prova è abbastanza semplice, poiché conta solo su ogni iterazione fino a raggiungere il punto di ripristino a 2,1 miliardi.

Ringraziamo Dave , che ha pubblicato l'approccio in pseudo codice nei commenti e a Bob Twells , da cui ho copiato il codice per un minimo di PHP quine.

Programma test (sloooooow):

<?php
$o = file_get_contents('quine.php');
for ($i = 0; $i < 22e8; $i++) {
    if ($i%2==0) exec('php q > p'); else exec('php p > q');
    $a = file_get_contents(($i%2==0) ? 'p' : 'q');
    echo "\r" . str_pad($i,6,' ') . ":\t$a";
    if ($a == $o) {
        die;
    }
}

Beh, almeno sono il primo a rispondere.


1
Nota a margine: è nell'ordine di ~ 10 ^ 9.322219295.
LegionMammal978,

8

Mathematica, periodo E8.5678 # 3 E2.1923 # 4 ~ E6.2695 # 3 # 2

Print[ToString[#0, InputForm], "[", #1 - 1 /. 0 -> "Nest[#!,9,9^9^99!]", "]"] & [Nest[#!,9,9^9^99!]]

Si noti che i punteggi sono descritti nella notazione Hyper-E . Le iterazioni sostituiscono il finale Nest[#!,9,9^9^99!]con le espansioni decimali di Nest[#!,9,9^9^99!]- 1, Nest[#!,9,9^9^99!]- 2, Nest[#!,9,9^9^99!]- 3, ..., 3, 2, 1 e ritorno a Nest[#!,9,9^9^99!].


i fattoriali non crescerebbero più velocemente?
Maltysen,

1
Non conosco Mathematica, ma non è una violazione delle regole per un quine - leggere il proprio codice sorgente? ToString[#0, InputForm]
daniero,

quindi solo 9 !!!! non funziona? idk cuz non ho il mio matematico rpi con me in questo momento.
Maltysen,

@Maltysen Che calcola il doppio fattoriale del doppio fattoriale di nove, o (9 !!) !! ≈ 2.116870635 · 10¹²⁰²
LegionMammal978

@daniero Voglio dire, l'idea è simile a una CJam standard {"_~"}_~, quindi immagino che dovrebbe essere valida ...
LegionMammal978

5

R, periodo casuale con aspettativa 2 ^ 19936-0,5

f=function(){
    options(scipen=50)
    body(f)[[4]]<<-sum(runif(623))
    0
    cat("f=")
    print(f)
}

Il generatore di numeri casuali predefinito di R ha un periodo di 2 ^ 19937-1 ed equidistribuzione in 623 dimensioni consecutive. Quindi, da qualche parte (ma solo una volta) nel suo periodo sarà un vettore di zero lungo 623. Quando ci arriviamo (e siamo allineati con l'inizio della sequenza) la somma dei successivi 623 numeri U [0,1] casuali sarà zero e torneremo al nostro programma originale.

Si noti che il programma con probabilità molto elevata passerà più volte nello stesso stato diverso da zero prima di tornare a zero. Ad esempio, la somma 311.5 è la più probabile e possono verificarsi molti modi, ma l'RNG consente al periodo per 0 di essere più lungo del periodo per 311.5.


Non sono sicuro di quale punteggio desideri assegnare questa voce: P
JDL

1
Secondo le regole: "Va bene dire qualcosa come" almeno 1.000.000 di iterazioni "piuttosto che fornire il numero esatto" Quindi secondo me è "almeno 1 iterazione" perché se diventiamo davvero fortunati al primo tentativo ...;)
YetiCGN,

A differenza di molte scappatoie standard come "Potrei generare qualche input casuale, la risposta è lì", questa è una prova davvero chiara che la risposta precisa è destinata a verificarsi e viene fornita una stima molto buona. Bello!
Andreï Kostyrka,

1
Una volta che il programma torna al suo stato di base una volta, avrà un periodo non casuale esattamente di 2 ^ 19937-1.
JDL,

L'output di questo non corrisponde al programma reale (manca un po 'di spazio). Inoltre, lo stato non verrà conservato tra le chiamate del programma, quindi il periodo non sarà un numero esatto, né sarà coerente
Jo King

1

JavaScript, periodo 9.007.199.254.700.000

Non vincerò, ma è stato divertente lavorare con JavaScript su questa sfida:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)

Segue il seguente ciclo:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699999-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699998-1||90071992547e5)
// etc...
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),3-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),2-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
// and so on

Nota: è possibile ridurre i 18 byte, rimuovendo solo ~ 0,08% del punteggio, in questo modo:

a="a=%s;console.log(a,uneval(a),%.0f-1||9e15)";console.log(a,uneval(a),1-1||9e15)

1

C, periodo 2.100.000.000

unsigned long long i;main(a){i=1;i*=21e8>i;printf(a="ungisned long long i;main(a){i=%d;i*=21e8>i;printf(a=%c%s%2$c,++i,34,a);}",++i,34,a);}

Basato sulla risposta PHP (ovviamente). Si aggiorna con spiegazione quando ho tempo.


1

C (gcc) , 66 byte, periodo 2 ^ 64

f(s){printf(s="f(s){printf(s=%c%s%1$c,34,s,%lu+1L);}",34,s,0+1L);}

Provalo online!

2 ^ 64 numeri sono disponibili in un unsigned longnumero intero. Pertanto, un periodo di 2 ^ 64.


1

Python 2

Periodo: 9((99↑↑(9((99↑↑(9((99↑↑(9↑↑5-1))9)-1))9)-1))9)+1

99(99↑↑12)+1

b=0;s="print'b=%d;s=%r;exec s'%(-~b%eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9))),s)";exec s

Provalo online!

Nel codice le b=0modifiche a b=1allora b=2e così via fino a quando non raggiungono b=decimal expansion of the periodquindi vengono ripristinateb=0


1
9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9è molto più alto di 9**9**99**99**99**99**99**99**99**99**99**99**99**99. Detto questo, potresti fare qualcosa di simile eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9)))per numeri MOLTO più alti.
Gorgogliatore

Cosa significa perido?
SS Anne,


1
@Mukundan Penso che potresti voler dire periodo ma non ne sono sicuro. Capisco cos'è la tetrazione.
SS Anne,

@SSAnne mi dispiace che sia stato un refuso, grazie per averlo sottolineato
Mukundan,

0

Gol> <> , 70 byte, periodo 325883196621297064957600206175719056476804879488288708188003274919860959534770101079512433396348062803055739640225395758790852315876868469390603793729639715908136196505908165227136154287969475839017544811926036808089596209081885772040898530121921794489026069641113281250

Altri saggi conosciuti come davvero grandi (3.25E270)

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

Questa è in realtà una versione modificata della risposta che ho inserito nell'iteratore da 500 byte

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||//if last is equal to 1 and length is 71, delete the delete char, if the last char is '~', delete and push 'H#', which will later return to 'H##', completing the cycle!
lPffXfX=?1:1=Q$~$~|          //if length is equal to 15^15^15, then start delete process(append ascii one)
:1)lPffXfX(Q?:|              //if the last character is not 1 (the delete checker), and length is less than 15^15^15, duplicate the last value and append
r2ssH##                      //push the " to the front and output the whole thing

Spero di aver ottenuto il punteggio giusto e non ci sono bug. Non esiste un modo reale per calcolare effettivamente questo valore, è teorico. Ma amico, questo è un numero enorme !!!

Provalo online!

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.