Haskell , 306 + 624 = 930 bajtów
Program 1: Anonimowa funkcja przyjmująca fikcyjny argument i zwracająca ciąg znaków.
(\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))"
Wypróbuj online!
Program 2: q[[40,...]]
na końcu jest anonimowa funkcja przyjmująca fikcyjny argument i zwracająca ciąg znaków.
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]]
Wypróbuj online!
Zestaw znaków 1 (zawiera spację):
"$()-:>E\`abcdefhilmnoprstuw×ÝáâäæéêñòóöđēĕħĮİĴ
Zestaw znaków 2 (zawiera nowy wiersz):
!'+,.0123456789<=@[]_qxz~
Ponieważ tylko zestaw 1 zawiera znaki spoza ASCII, ich bajty UTF-8 są również rozłączne.
Jak to działa
Program 1 jest ogólnie napisany z wyrażeniami lambda, spacjami i nawiasami, swobodnym użyciem wbudowanych funkcji alfanumerycznych oraz danymi quine jako literałami łańcuchowymi na końcu.
- Własny kod programu 1 zamienia się w dane literału łańcuchowego, po prostu otaczając go znakami cudzysłowu.
- Aby to poprzeć, po każdym odwrotnym ukośniku następuje
a
lub b
, które tworzą prawidłowe sekwencje specjalne, które przechodzą w drugą stronę show
.
- Inną korzyścią jest to, że małe
a
, b
i c
są tylko małe litery, których kody ASCII są mniej niż 100, oszczędzając cyfra w kodowaniu liczbowej wykorzystywanego przez program 2.
- Dosłowne kodowanie ciągów kodu podstawowego programu 2 jest bardziej zaciemnione dzięki użyciu kodu Unicode innego niż ASCII: Każdy znak ma 182 dodanych do punktu kodowego, aby zapewnić, że nie zachodzą na siebie znaki oryginalne.
- 182 było 128, dopóki nie zdałem sobie sprawy, że mogę nadużyć faktu, że 182 jest dwa razy dłuższy od literału łańcucha dla kodu programu 1, aby skrócić dekodowanie. (Jako bonus, program 2 może korzystać z nowych linii).
Program 2 jest na ogół napisany z równaniami funkcji najwyższego poziomu (z wyjątkiem ostatniego anonimowego), literałami znaków i liczbami dziesiętnymi, składnią list / zakresu i operatorami, a także danymi quine jako listą Int
s na końcu.
- Główny kod Programu 1 jest zakodowany jako lista jego punktów kodowych, z końcowym podwójnym cytatem.
- Główny kod programu 2 jest zakodowany jako lista punktów kodowych literału łańcucha używanego w programie 1, wciąż przesuniętego w górę o 182.
Przewodnik, program 1
b
i c
są wartościami literałów łańcuchowych odpowiednio dla programu 2 i 1, podanymi jako ostateczne argumenty wyrażenia lambda. ()
jest fikcyjnym argumentem mającym jedynie na celu spełnienie zasady PPCG, zgodnie z którą program powinien definiować funkcję.
foldr(\a->map pred)b(show()>>c)
dekoduje ciąg b
do kodu podstawowego programu 2, stosując map pred
do niego liczbę razy równą długości show()>>c == c++c
lub 182
.
tail(show c)
konwertuje ciąg c
do kodu podstawowego programu 1, dołączając końcowy podwójny cudzysłów.
:pure b
łączy to na liście z ciągiem znaków b
.
map(map fromEnum)$
konwertuje ciągi znaków na listy punktów kodowych.
`mappend`show(...)
serializuje wynikową listę list i ostatecznie dołącza ją do podstawowego kodu programu 2.
Przewodnik, program 2
- Najwyższy poziom
z~z=[[['@','0'..]!!4..]!!z]
to funkcja konwertująca punkty kodowe z powrotem na znaki (konieczne do napisania, ponieważ nie wszystkie znaki toEnum
są dostępne).
- Wywoływany jest również argument punktu kodowego
z
. Znacznik lenistwa ~
nie działa w tej pozycji, ale unika znaku spacji.
['@','0'..]
jest zakresem wstecznej listy kroków, zaczynając od kodu ASCII 64, a następnie zeskakując 16 w dół na każdym kroku.
- Zastosowanie
!!4
do tego nadaje \NUL
charakter.
- Zawijanie tego w
[ ..]
zakresie daje listę wszystkich znaków, które !!z
indeksuje.
- Postać jest ostatecznie umieszczona na liście singletonów. Pozwala to na mapowanie funkcji
z
na listach przy użyciu =<<
zamiast niedostępnych map
i <$>
.
- Najwyższy poziom
q[x,q]_=z=<<x++q++[34,34]++x
to funkcja konstruująca program 1 z listy danych quine.
x
to dane dla rdzenia programu 1 (w tym końcowy podwójny cudzysłów), a wewnętrzna q
to zaciemnione dane dla rdzenia programu 2. _
to kolejny fałszywy argument wyłącznie po to, aby końcowa anonimowa funkcja była funkcją zamiast tylko łańcucha.
x++q++[34,34]++x
łączy elementy, w tym dwa znaki podwójnego cudzysłowu z kodem ASCII 34.
z=<<
konstruuje program 1 poprzez odwzorowanie z
konkatenacji w celu konwersji punktów kodowych na znaki.
- Final
q[[40,...]]
to anonimowa funkcja łącząca się q
z danymi quine.