Skip to content

Iper sulle quine

Il nostro team di lavoro ha dedicato molto tempo alla ricerca della risposta alla tua domanda, ti forniamo la soluzione, quindi la nostra speranza è che ti sarà di grande aiuto.

Soluzione:

Befunge-98, ordine infinito, 545238 36 byte

Secondo approccio - ordine infinito, 36 byte

Questo programma si interrompe alla 34a iperquinta, poiché il valore ASCII di " interromperebbe l'interpretazione della stringa (e al 59°, ;), ma abbiamo spostato la memorizzazione di questo valore in una posizione che non verrà mai eseguita (cioè (0, 1) ).(0, 1)invece di (0, 0)).

1+::0*x01pn'!1+:#jr;,[email protected]!:kg10;#"

Prova in linea: 1, 2, 10, 34, 42

Spiegazione

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
[email protected]                                                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.

Primo approccio - ordine 34, 52 byte (usa l'introspezione, quindi tecnicamente non è legale)

Per il motivo indicato nel post precedente, questo programma si interromperebbe all'ordine 34 (anche se non l'ho testato).

1+::0*x:00p'1k:00gk,1#;:00g*0g00gk:$00gk,1+:'[email protected];

Provatelo online!

<>, ordine infinito, 178 byte

Il programma contiene un capoverso.

^
.
*
&
:
&
+
*
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
'

Provare online: 1, 2, 3, 10 (l'ultimo richiede un po' di tempo per essere eseguito).

Script Retina per generare sorgenti da un programma lineare.

Spiegazione

L'idea principale è quella di trasformare la quine in verticale, in modo che il flusso di controllo effettivo non sia influenzato dalla ripetizione. Ad esempio, la seconda iperquazione inizia come:

^^

..

**

Poiché ci muoviamo solo attraverso la prima colonna, non dobbiamo preoccuparci dei caratteri ripetuti. Inoltre, quando spingiamo la maggior parte del codice come stringa con 'si inserisce uno spazio per ogni riga vuota, in modo da determinare il numero di ripetizioni. Detto questo, ci sono alcune limitazioni dovute a queste righe vuote:

  • Non possiamo usare " per spingere grandi numeri come codici di caratteri nella parte principale della quine, perché questo spingerebbe ulteriori 32che non vogliamo.
  • Non possiamo usare ? o ! perché saltano solo il carattere successivo, che in questo caso sarebbe uno spazio (quindi non salterebbero effettivamente il comando successivo).

Quindi, tutto il flusso di controllo viene eseguito con salti espliciti (goto 2D, in pratica), i cui offset effettivi devono essere calcolati in base al numero di ripetizioni.

Diamo quindi un'occhiata al codice vero e proprio. Iniziamo con ^ quindi il codice viene eseguito dal basso verso l'alto. Per una lettura più semplice, scriviamo il codice attuale in ordine di esecuzione (e lasciamo perdere il punto ^ perché non viene mai più eseguito):

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

Il ' è la tecnica di quining standard per ><> (e Befunge, credo). Passa alla modalità stringa, il che significa che i caratteri incontrati vengono spinti nello stack fino al successivo ' viene incontrato. Le righe vuote sono implicitamente imbottite di spazi, motivo per cui si ottengono tutti gli spazi intermedi. Le righe vuote alla fine del programma vengono ignorate. Quindi, dopo che l'IP si avvolge e colpisce il punto ' abbiamo la prima colonna del programma in pila, eccetto la riga ' .'stesso.

Vediamo come usarlo per stampare l'intero programma.

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.

Il programma termina quando lo stack è vuoto e il primo ciclo interno non riesce a stampare un altro carattere.

Hai la possibilità di incoraggiare il nostro impegno pubblicando un commento o lasciando una valutazione, lo apprezziamo.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.