Haskell , 306 + 624 = 930 байт
Програма 1: Анонімна функція, яка приймає фіктивний аргумент і повертає рядок.
(\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))"
Спробуйте в Інтернеті!
Програма 2: q[[40,...]]
наприкінці - анонімна функція, яка бере фіктивний аргумент і повертає рядок.
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]]
Спробуйте в Інтернеті!
Набір символів 1 (включає пробіл):
"$()-:>E\`abcdefhilmnoprstuw×ÝáâäæéêñòóöđēĕħĮİĴ
Набір символів 2 (включає новий рядок):
!'+,.0123456789<=@[]_qxz~
Оскільки лише набір 1 містить символи, що не належать до ASCII, їх байти UTF-8 також роз'єднані.
Як це працює
Програма 1, як правило, записується з лямбда-виразами, пробілами та дужками, вільним використанням вбудованих буквено-цифрових функцій та з даними quine як рядкові букви в кінці.
- Власний основний код програми 1 перетворюється на рядкові буквальні дані, просто оточуючи його лапки.
- Щоб підтримати це, після кожного зворотного косого кута слідує
a
або b
, що утворює дійсні послідовності втечі, що проходять по колу show
.
- Ще одна крихітної перевага полягає в тому
a
, b
і c
є тільки малими літерами , чия ASCII коду менше , ніж 100, заощадивши цифри в числовому кодуванні , використовуваної програмою 2.
- Рядкове буквене кодування основного коду програми 2 є більш прихованим, використовуючи Unicode, який не є ASCII: Кожен символ додає 182 до своєї кодової точки, щоб переконатися, що немає перекриття з вихідними символами.
- Раніше 182 було 128, поки я не зрозумів, що можу зловживати тим фактом, що 182 вдвічі перевищує лінійний рядок для коду програми 1 для скорочення декодування. (В якості бонусу програма 2 може використовувати нові рядки.)
Програма 2, як правило, пишеться з рівняннями функцій верхнього рівня (крім остаточного анонімного), символьними буквами та десятковими числами, синтаксисом списку / діапазону та операторами, а також дані quine як список списків Int
s в кінці.
- Основний код програми 1 кодується у вигляді списку кодових точок із остаточною подвійною цитатою.
- Основний код програми 2 кодується як перелік точок коду рядкового літералу, що використовується в програмі 1, все ще зміщений вгору на 182.
Покрокова інструкція, програма 1
b
і c
є значеннями літеральних рядків для програм 2 і 1 відповідно, наведені як кінцеві аргументи до лямбда-виразу. ()
є фіктивним аргументом виключно для задоволення правила PPCG про те, що програма повинна визначати функцію.
foldr(\a->map pred)b(show()>>c)
декодує рядок b
до основного коду програми 2, застосовуючи map pred
до нього кілька разів рівну довжині show()>>c == c++c
, або 182
.
tail(show c)
перетворює рядок c
до основного коду програми 1, додаючи остаточну подвійну лапочку.
:pure b
поєднує це у списку з рядком b
.
map(map fromEnum)$
перетворює рядки в списки кодових точок.
`mappend`show(...)
серіалізує отриманий список списків і, нарешті, додає його до основного коду програми 2.
Покрокова інструкція, програма 2
- Топлерівень
z~z=[[['@','0'..]!!4..]!!z]
- це функція, що перетворює кодові точки назад у символи (необхідні для запису, оскільки не всі символи toEnum
доступні.)
- Аргумент його кодової точки також називається
z
. Маркер ліні ~
в цьому положенні не впливає, але уникає космічного характеру.
['@','0'..]
являє собою діапазон списку кроків, що починається назад, починаючи з коду ASCII 64, потім стрибаючи 16 вниз на кожному кроці.
- Звернення
!!4
до цього надає \NUL
характеру.
- Розгортання цього
[ ..]
діапазону дає список усіх символів, які !!z
індексує.
- Персонаж нарешті загорнутий у одиночний список. Це дозволяє відображати функцію
z
за списками, використовуючи =<<
замість недоступних map
та <$>
.
- Топлевель
q[x,q]_=z=<<x++q++[34,34]++x
- це функція, що конструює програму 1 зі списку даних quine.
x
- це дані для ядра програми 1 (включаючи остаточну подвійну цитату), а внутрішня q
- це затуманені дані для ядра програми 2. _
- ще один фіктивний аргумент виключно для того, щоб зробити остаточну анонімну функцію функцією замість просто рядка.
x++q++[34,34]++x
поєднує фрагменти, включаючи дві подвійні лапки з кодом ASCII 34.
z=<<
будує програму 1 шляхом відображення z
конкатенації для перетворення з кодових точок в символи.
- Фінал
q[[40,...]]
- це анонімна функція, що поєднується q
з даними quine.