CJam, ( 58 56 54 48 46 x 2) * 48% = 44.16
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
quale stampa
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
I caratteri non spaziali in ciascuna riga rimangono gli stessi tra le due stringhe reciproche.
Ma ora la parte davvero dolce:
{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~
è un quine! :)
Provalo qui.
Come funziona
Ti consiglio di leggere prima la spiegazione sull'altra mia presentazione, in quanto spiega le basi del quining in CJam in generale.
Questo è un po 'più complicato. Per il quine reciproco, come nell'altro caso, modifico la rappresentazione in forma di stringa del blocco aggiungendo spazi prima o dopo ogni riga e scambiando uno 0 con un 2, in modo che il programma risultante metta gli spazi all'estremità opposta.
Si noti che gli spazi non influiscono affatto sui reciproci quines. Nel primo, sono in un blocco, che non è realmente utilizzato, e nel secondo sono attorno all'intero codice.
Per ottenere un quine regolare quando si combinano entrambi, è necessario trovare un modo per evitare di apportare tutte queste modifiche. Si noti che la struttura dello spazio bianco e del codice significa che combinando entrambi, inseriamo l'intero quine nell'altro. Quindi, se inseriamo l'intero codice di modifica in un blocco, possiamo eseguire quel blocco in base al suo contenuto effettivo.
Quindi ora ho questo blocco ... per le quine reciproche, contiene solo il codice che in realtà voglio eseguire. Per il quine combinato, contiene anche di nuovo l'intero quine, in una posizione casuale, il che non ha alcun senso ... ma poiché è un blocco, non viene eseguito automaticamente. Quindi possiamo determinare se modificare la stringa in base al contenuto di quel blocco. Questo è ciò che _`'"#)!
serve. Duplica il blocco, lo converte in una stringa, cerca il carattere "
(che, nelle stringhe reciproche, appare solo all'esterno del blocco) - la ricerca ritorna -1
se il carattere non viene trovato e un intero positivo altrimenti -, incrementa il risultato e lo nega logicamente. Quindi, se è "
stato trovato un, questo produce 0
altrimenti 1
. Adesso lo facciamo e basta*
, che esegue il blocco una volta, se il risultato era 1 e per niente altrimenti.
Infine, ecco come funziona il codice di modifica:
_,94\m2/S*a_+\*N/23f/Wf%N*
_, "Duplicate the quine string and get its length.";
94\m "Subtract from 94.";
2/ "Divide by two.";
S* "Create a string with that many spaces. This will be
an empty string for the first mutual quine, and contain
23 spaces for the second mutual quine.";
a_+ "Create an array that contains this string twice.";
\* "Join the two copies together with the quine string.";
N/ "Split into lines.";
23f/ "Split each line into halves (23 bytes each).";
Wf% "Reverse the two halves of each line.";
N* "Join with a newline.";
Rivendicazione della taglia, (12 x 10) * 48% = 57.6
Si scopre che questo codice può essere suddiviso su più righe molto facilmente con alcune modifiche. Aggiungiamo 2 caratteri, per ottenere 48 di fila, che possiamo quindi dividere convenientemente per 8, in modo da avere 8 righe con 6 caratteri di codice e 6 spazi. Per fare ciò dobbiamo anche cambiare alcuni numeri e riorganizzare uno o due operatori, in modo che non vengano suddivisi su entrambe le righe. Questo ci dà una versione funzionante con dimensioni 12 x 8 ... una tantum. Quindi aggiungiamo solo due righe che non fanno nulla (premi un 1, fai scoppiare un 1, premi un 1, fai scoppiare un 1 ...), quindi arriva a 12 x 10 :
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
Come il precedente questo produce
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
(Nota a margine: non è necessario continuare a alternare sinistra e destra sulle linee intermedie, solo la posizione della prima e dell'ultima linea sono importanti. Sinistra e destra possono essere scelte arbitrariamente per tutte le altre linee.)
E per pura coincidenza, anche il quine completo funziona ancora:
{`"_~"{`"_~"
+{129X+{129X
$,m2/S$,m2/S
*a_+\**a_+\*
N/6f/1N/6f/1
;1;1;1;1;1;1
;1;1;1;1;1;1
;Wf%N*;Wf%N*
}_`'"#}_`'"#
)!*}_~)!*}_~
(Dico una coincidenza, perché la parte che si occupa di non eseguire il codice interno ora viene stranamente intervallata dall'altra quina, ma sembra comunque funzionare bene.)
Detto questo, avrei potuto aggiungere 44 righe 1;
alla mia presentazione originale per soddisfare il requisito di generosità, ma 12 x 10
sembra molto più ordinato. ;)
Edit: Haha, quando ho detto "pura coincidenza" non avrei potuto essere più esatto. Ho esaminato il modo in cui ora funziona il quine finale, ed è assolutamente ridicolo. Esistono tre blocchi nidificati (4 in realtà, ma il più interno è irrilevante). L'unica parte importante del più interno di quei 3 blocchi è che contiene un "
(e non quello che ha fatto nella presentazione originale, ma proprio '"
quello usato alla fine per verificare lo stesso personaggio). Quindi la struttura di base del quine è:
{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~
Analizziamo che:
{`"_~" }_~ "The standard CJam quine.";
{`"_~"+ }_~ "Another CJam quine. Provided it doesn't do
anything in the rest of that block, this
will leave this inner block as a string on
the stack.";
) "Slice the last character off the string.";
! "Negate... this yields 0.";
* "Repeat the string zero times.";
Quindi questo fa davvero qualche magia divertente, ma poiché il blocco interno lascia una singola stringa in pila, )!*
sembra trasformarla in una stringa vuota. L'unica condizione è che le cose nel blocco interno dopo +
non facciano altro nello stack, quindi diamo un'occhiata a questo:
{___'"___} "Push a block which happens to contain
quotes.";
_`'"#)!* "This is from the original code and just
removes the block if it does contain
quotes.";