Haskell , 306 + 624 = 930 byte
Programma 1: una funzione anonima che prende un argomento fittizio e restituisce una stringa.
(\b c()->foldr(\a->map pred)b(show()>>c)`mappend`show(map(map fromEnum)$tail(show c):pure b))"İĴİóđđđÝöÝâÝæÝääē××êääē××İēÀħđĮâħēĕóİóòòĮááħááđéêâéêēááĮÀħ""(\b c()->foldr(\a->map pred)b(show()>>c)`mappend`show(map(map fromEnum)$tail(show c):pure b))"
Provalo online!
Programma 2: q[[40,...]]
alla fine è una funzione anonima che prende un argomento fittizio e restituisce una stringa.
z~z=[[['@','0'..]!!4..]!!z]
q[x,q]_=z=<<x++q++[34,34]++x
q[[40,92,98,32,99,40,41,45,62,102,111,108,100,114,40,92,97,45,62,109,97,112,32,112,114,101,100,41,98,40,115,104,111,119,40,41,62,62,99,41,96,109,97,112,112,101,110,100,96,115,104,111,119,40,109,97,112,40,109,97,112,32,102,114,111,109,69,110,117,109,41,36,116,97,105,108,40,115,104,111,119,32,99,41,58,112,117,114,101,32,98,41,41,34],[304,308,304,243,273,273,273,221,246,221,226,221,230,221,228,228,275,215,215,234,228,228,275,215,215,304,275,192,295,273,302,226,295,275,277,243,304,243,242,242,302,225,225,295,225,225,273,233,234,226,233,234,275,225,225,302,192,295]]
Provalo online!
Set di caratteri 1 (include spazio):
"$()-:>E\`abcdefhilmnoprstuw×ÝáâäæéêñòóöđēĕħĮİĴ
Set di caratteri 2 (include newline):
!'+,.0123456789<=@[]_qxz~
Poiché solo il set 1 contiene caratteri non ASCII, anche i loro byte UTF-8 sono disgiunti.
Come funziona
Il programma 1 è generalmente scritto con espressioni lambda, spazi e parentesi, uso gratuito delle funzioni alfanumeriche incorporate e con i dati di quine come valori letterali di stringa alla fine.
- Il codice core del programma 1 viene trasformato in dati letterali di stringa semplicemente racchiudendolo tra virgolette.
- A supporto di ciò, ogni barra rovesciata è seguita da
a
o b
, che formano sequenze di escape valide che vanno di andata e ritornoshow
.
- Un altro vantaggio è che piccolo
a
, b
e c
sono le solo minuscole cui codici ASCII sono meno di 100, risparmiando una cifra nella codifica numerica utilizzata dal programma 2.
- La codifica letterale stringa del codice core del programma 2 è più offuscata utilizzando Unicode non ASCII: ogni carattere ha aggiunto 182 al suo punto di codice per garantire che non vi siano sovrapposizioni con i caratteri originali.
- 182 era 128, fino a quando mi sono reso conto che avrei potuto abusare del fatto che 182 è il doppio della lunghezza della stringa letterale per il codice del programma 1 per abbreviare la decodifica. (Come bonus, il programma 2 può usare newline.)
Il programma 2 è generalmente scritto con equazioni di funzione di livello superiore (tranne quella anonima finale), valori letterali dei caratteri e numeri decimali, sintassi elenco / intervallo e operatori e con i dati quine come un elenco di elenchi di Int
s alla fine.
- Il codice principale del Programma 1 è codificato come un elenco dei suoi punti di codice, con una doppia virgoletta finale.
- Il codice core del programma 2 è codificato come l'elenco di punti di codice del valore letterale di stringa utilizzato nel programma 1, spostato ancora verso l'alto di 182.
Procedura dettagliata, programma 1
b
e c
sono i valori dei letterali stringa per il programma 2 e 1, rispettivamente, dati come argomenti finali all'espressione lambda. ()
è un argomento fittizio solo per soddisfare la regola di PPCG secondo cui il programma dovrebbe definire una funzione.
foldr(\a->map pred)b(show()>>c)
decodifica la stringa b
nel codice principale del programma 2 applicando map pred
ad essa un numero di volte uguale alla lunghezza di show()>>c == c++c
, o 182
.
tail(show c)
converte la stringa c
nel codice principale del programma 1, con l'aggiunta di una doppia virgoletta finale.
:pure b
combina questo in un elenco con la stringa b
.
map(map fromEnum)$
converte le stringhe in elenchi di punti di codice.
`mappend`show(...)
serializza l'elenco risultante di elenchi e infine lo aggiunge al codice principale del programma 2.
Procedura dettagliata, programma 2
- Il livello superiore
z~z=[[['@','0'..]!!4..]!!z]
è una funzione che converte i punti di codice in caratteri (necessario per scrivere poiché non tutti i caratteri intoEnum
sono disponibili).
- Viene anche chiamato l'argomento punto di codice
z
. L'indicatore di pigrizia~
non ha alcun effetto in questa posizione ma evita un carattere spaziale.
['@','0'..]
è un intervallo di elenchi di gradini all'indietro che inizia con il codice ASCII 64, quindi salta di 16 in giù per ogni passaggio.
- Applicare
!!4
a questo dà un \NUL
carattere.
- Avvolgendolo in un
[ ..]
intervallo si ottiene un elenco di tutti i caratteri, che viene !!z
indicizzato.
- Il personaggio è finalmente racchiuso in una lista singleton. Ciò consente di mappare la funzione
z
sugli elenchi utilizzando =<<
anziché l'indisponibile map
e <$>
.
- Il livello superiore
q[x,q]_=z=<<x++q++[34,34]++x
è una funzione che costruisce il programma 1 dall'elenco dei dati di Quine.
x
sono i dati per il core del programma 1 (inclusa una doppia virgoletta finale) e l'interno q
è i dati offuscati per il core del programma 2. _
è un altro argomento fittizio solo per rendere la funzione anonima finale una funzione anziché una semplice stringa.
x++q++[34,34]++x
concatena i pezzi, tra cui due virgolette doppie con codice ASCII 34.
z=<<
costruisce il programma 1 mappando z
sulla concatenazione per convertire da punti di codice a caratteri.
- Il finale
q[[40,...]]
è una funzione anonima che si combina q
con i dati di Quine.