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
, которые образуют допустимые escape-последовательности, проходящие в обратном направлении show
.
- Еще одна крошечной преимущество заключается в том
a
, b
и c
являются только строчными буквами , чья ASCII кода меньше , чем 100, сэкономив цифры в числовом кодировке , используемой программой 2.
- Строковое литеральное кодирование основного кода программы 2 более запутанно с использованием не-ASCII Unicode: каждый символ имеет 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
данные квин.