В предыдущих приключениях серии блогов Quine мы изучали, как писать собственные Quine и Intron. Сегодня мы увидим, что такое QuineRelays и как можно использовать интроны для их создания.
Представьте себе круг программ, каждая из которых написана на разных языках. Каждая программа в этом круге имеет единственную цель: распечатать исходный код следующей программы в последовательности. Затем последняя программа замыкает цикл, печатая исходный код самой первой программы.
По сути, QuineRelays представляет собой набор из n программ на n разных языках, таких как:
Давайте посмотрим несколько примеров, чтобы лучше понять концепцию.
Этот QuineRelay 2-го порядка содержит программу JavaScript, которая печатает программу Python, а затем обратно печатает исходную программу JavaScript. Это динамичный дуэт самовоспроизведения.
JavaScript → Python ⥀
JavaScript: попробуйте онлайн!
console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q []})())`)})`)())
Python: попробуйте онлайн!
print("console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q []})())`)})`)())")
Все становится еще интереснее с QuineRelay 3-го порядка. Этот начинается с программы на Haskell, которая выводит программу на Python, которая выводит программу на Ruby, и, наконец, программа Ruby возвращается к исходной программе на Haskell.
Haskell → Python2 → Ruby ⥀
Haskell: попробуйте онлайн!
q a b c=putStrLn $ b [toEnum 10,'q','('] show b [','] show c [','] show a [')'] main=q "q a b c=putStrLn $ b [toEnum 10,'q','('] show b [','] show c [','] show a [')']" "def q(a,b,c):print b chr(10) 'q(' repr(b) ',' repr(c) ',' repr(a) ')'" "def e(x) return 34.chr x 34.chr end;def q(a,b,c) print b 10.chr 'main=q ' e(b) ' ' e(c) ' ' e(a) ' ' 10.chr end"
Python2: попробуйте онлайн!
def q(a,b,c):print b chr(10) 'q(' repr(b) ',' repr(c) ',' repr(a) ')' q("def q(a,b,c):print b chr(10) 'q(' repr(b) ',' repr(c) ',' repr(a) ')'","def e(x) return 34.chr x 34.chr end;def q(a,b,c) print b 10.chr 'main=q ' e(b) ' ' e(c) ' ' e(a) ' ' 10.chr end","q a b c=putStrLn $ b [toEnum 10,'q','('] show b [','] show c [','] show a [')']")
Руби: Попробуйте онлайн!
def e(x) return 34.chr x 34.chr end;def q(a,b,c) print b 10.chr 'main=q ' e(b) ' ' e(c) ' ' e(a) ' ' 10.chr end q("def e(x) return 34.chr x 34.chr end;def q(a,b,c) print b 10.chr 'main=q ' e(b) ' ' e(c) ' ' e(a) ' ' 10.chr end","q a b c=putStrLn $ b [toEnum 10,'q','('] show b [','] show c [','] show a [')']","def q(a,b,c):print b chr(10) 'q(' repr(b) ',' repr(c) ',' repr(a) ')'")
Вот QuineRelay 4-го порядка: Ruby → Java → C# → Python ⥀
Гитхаб
В разных культурах существует несколько общих символов. Один из них — Уроборос, упоминаемый в египетской, греческой, римской, индуистской, сибирской, скандинавской, африканской и южноамериканской мифологии. Уроборос — древний символ, изображающий змею или дракона, пожирающего свой хвост, символизирующий вечный цикл созидания и разрушения.
В скандинавской мифологии Ёрмунганд — колоссальный змей, средний ребенок Локи и великанши Ангрбоды. Один бросил Ёрмунганда в океан, окружающий Мидгард (царство людей), где змей стал настолько огромным, что окружил мир и схватился за собственный хвост. В связи с тем, что он окружает Мидгард (Землю), его называют Мировым Змеем – Уроборосом. Ёрмунганд, выпускающий свой хвост, является одним из признаков начала Рагнарёка (последней битвы мира).
Реле Куайна довольно четко воплощают этот символизм, поскольку каждая программа в цикле порождает следующую только для того, чтобы в конце возродиться заново, поэтому их называют программами Уроборос
Держитесь за свои места. Вот QuineRelay Уроборос 128-го порядка. Да, вы правильно прочитали. 128 !!!
Ruby → Rust → Scala → ... (ещё 120) ... → Python → R → Ratfor → rc → REXX ⥀
Гитхаб
Как будто это недостаточно впечатляюще, здесь есть пасхальное яйцо. Исходный код Ruby при уменьшении масштаба содержит дракона Уроборос!
Давайте запустим интрон Python, который мы написали ранее, и попробуем превратить его в QuineRelay 2-го порядка.
Python Intron: попробуйте онлайн!
intron = 'wubbalubbadubdub' data = "print('intron =', repr(intron)); print('data =', repr(data)); print(data)" print('intron =', repr(intron)); print('data =', repr(data)); print(data)
Используя магию интронов, теперь мы можем легко поместить в интрон часть кода родственного Куайна другого языка. Создание программы вида:
Питон:
intron = "code part of sibling" data = "code part of self" print('intron =', repr(intron)); print('data =', repr(data)); print(data)
Поскольку каждая переменная просто действует как данные другого Куайна. Давайте переименуем данные и интрон в d1 и d2 соответственно.
Питон:
d1 = "code part of self" d2 = "code part of sibling" print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d1)
Теперь d2 действует как интрон, но приведенная выше программа все еще пыталась напечатать часть своего кода. Чтобы он напечатал исходный код следующего, давайте в конце напечатаем(d2) вместо print(d1).
Питон:
d1 = "code part of self" d2 = "code part of sibling" print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)
Мы уже знаем, что содержимое d1 — это всего лишь копия строки 3. Но содержимого d2 у нас пока нет.
Скажем, мы хотели создать QuineRelay с помощью JavaScript. Напишем аналогичный интрон на JS.
JavaScript:
d1 = "code part of sibling" d2 = "code part of self" console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1);
Теперь, строка 3 приведенного выше JS-интрона представляет собой код родственной программы, которую мы хотели!
Вставьте код друг друга в качестве интронов в другой.
Примечание. Нам нужно добавить d1 '' в js, чтобы избежать несоответствий в кавычках
Python: попробуйте онлайн!
d1 = "print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)" d2 = "console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 '');" print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)
JavaScript: попробуйте онлайн!
d1 = "print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)" d2 = "console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 '');" console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 '');
Вот и все. Это настоящее QuineRelay 2-го порядка! Программа Python, которая печатает программу JavaScript, которая циклически печатает исходную программу Python.
Создание QuineRelay — это упражнение в творческом программировании и понимании того, как разные языки представляют строки и манипулируют ими. Он включает в себя объединение интронов из различных программ, каждая из которых содержит код для репликации своего следующего соседа.
По сути, реле n-го порядка — это игра, состоящая из n умных способов выхода из кавычек на n языках программирования.
Следите за обновлениями на MultiQuine!
Источники и ссылки:
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3