Ваша задача проста: написать программу (или функцию), которая не требует ввода и выводит (или возвращает) свой исходный код. Подвох заключается в том, что когда программа обернута "quotes"
(символ Unicode 34), она должна снова вывести свой (теперь заключенный в кавычки) исходный код.
Стандартные правила для Quines применяются. Это код-гольф , поэтому выигрывает самая короткая (в байтах) программа.
!
..."
? Некоторые языки поддерживают два или три символа кавычки.Ответы:
Noodel ,
97 байтовЭта версия работает так же, как и другая, просто я забыл, что у Нуделя есть способ запустить блок кода один раз, и я создал язык ...
Ḷ1ḥ-Ð1ḥ@€
Попытайся:)
Как это устроено
Quote-безопасности
Размещение
"
символа до и после программы работает, потому что у Noodel есть набор символов, посвященных тому, что я называю печатными . Они сразу же разбираются как строковые литералы, когда помещаются сами по себе и позволяют легко распечатать что-то на экране. Так что в отличие от большинства языков, Нудель видит нормальный набор ASCII, который считается достойным печати, как прямые строковые литералы (за исключением пробелов и перевода строки), в которых цитирование кода просто рассматривается как нажатие на строки."Попытайся:)"
обрывки
источник
e
является действительным. Вопрос не о символе, закодированном как байт 34, а о"
"
? (Извините, просто пытаюсь убедиться, что я понимаю, что вы говорите) Кроме того, я должен удалить весь текст в ответе, касающемся использованияe
?"
работает, я бы просто удалил обсуждение и просто использовал"
.Python
23,181152130124122 байтаПопробуйте онлайн! TIO поставляется с верхним и нижним колонтитулами, которые автоматически проверяют действительность квин. Вы можете очистить их, чтобы просто запустить Quine.
Этот код работает с использованием строк в тройных кавычках в Python.
""" """
равно' '
и"""" """
равно'" '
.Код использует
exec
, но не для «не-quiney», способ выполнения данных в виде кода, просто для установки переменной внутри выражения.exec
Правильно закодированы в данных, тоже.Первое утверждение сравнивает строку, возможно с кавычкой, до
" "
, и устанавливает переменнуюoct
соответственно. (Переменная могла быть любой короткой встроенной.)Остальная часть кода затем реализует традиционную Python quine, используя
%r
форматирование строк, с некоторым дополнительным кодом, который удаляет лишние кавычки, еслиoct
не изменены.Альтернативная версия, использующая читерство,
exec
имеет размер 126 байт с менее повторяющимся кодом:Попробуйте онлайн!
источник
StandardML ,
182 176108 байтВерсия без кавычек: попробуйте это на codingground.
Цитируемая версия: попробуйте на codingground.
Обратите внимание, что вывод выглядит примерно так
потому что код интерпретируется декларацией по декларации (каждая
;
заканчивается декларацией) и показывает значение и тип каждой декларации.Фон
В SML есть формула вида
<code>"<code in quotes>"
:и один в форме
"<code in quotes>"<code>
:Оба полагаются на тот факт, что
<code>
-part не содержит кавычек и, следовательно, может быть заключен в кавычки без необходимости избегать чего-либо,"
необходимые для вывода квинуса определяютсяstr(chr 34)
.Они также сильно зависят от неявного идентификатора.
it
который используется, когда в объявлении не указан явный идентификатор.В первой квине
str(chr 34);
связываетсяit
со строкой, содержащей"
,fn x=>
запускает анонимную функцию, принимающую один аргументx
, затем объединяетx^it^x^it
и печатает полученную строку. Эта анонимная функция напрямую применяется к строке, содержащей программный код, поэтому конкатенацияx^it^x^it
дает<code>"<code>"
.Вторая квинна начинается только с кода программы в виде строки, с
";str(chr 34)^it;print(it^it)";
которой связаноit
. Затемstr(chr 34)^it;
конкатенирует кавычку с началом строки и, поскольку опять же не указан явный идентификатор, результирующая строка"<code>
связывается сit
. Наконецprint(it^it)
соединяет строку с собой"<code>"<code>
которая затем печатается.объяснение
Редактировать: больше не в курсе 108-байтовой версии, однако вы можете понять это и после прочтения этого объяснения.
Quine-safe quine сочетает в себе оба вышеуказанных подхода и сам по себе имеет форму
"<code>"<code>
. Поместив это снова в кавычки доходности""<code>"<code>"
, мы получим пустую строку, а затем квинус другой формы.Это означает, что программа либо получает свой собственный источник в форме
"<code>
с помощью идентификатораit
, либоit
является справедливой,"
и мы получаем наш собственный источник в<code>
качестве аргумента и, следовательно, должны быть функцией, которая обрабатывает такой аргумент.Чтобы определить, в каком случае мы находимся, мы проверяем, больше ли размер
it
единицы, чем 1. Если нет, тоit
есть,"
и мы находимся во втором случае, поэтомуelse
-part возвращает анонимную функцию,fn x=>print(it^it^x^it^x^it)
которая затем вызывается, потому что за ней следует источник в виде строки. , Обратите внимание на начало,it^it^
которое необходимо для пустой строки в начале программы.Если
size it
больше 1, мы находимся вthen
-part и просто выполняемprint(it^it)
, верно? Не совсем, потому что я не сказал вам, что SML строго типизирован, что означает, что у условногоif <cond> then <exp_1> else <exp_2>
выражения всегда должен быть один и тот же тип, что опять же означает, что выражения<exp_1>
и<exp_2>
должны иметь одинаковый тип. Мы уже знаем типelse
детали: анонимная функция, которая принимает строку и затем вызывает,print
имеет типstring -> <return type of print>
иprint
типstring -> unit
(unit
в некотором роде похожа наvoid
другие языки), поэтому результирующий тип сноваstring -> unit
.Таким образом, если бы
then
деталь была простоprint(it^it)
с типомunit
, мы получили бы ошибку несоответствия типов. Так как насчетfn _=>print(it^it)
? (_
это подстановочный знак для неиспользуемого аргумента). Эта анонимная функция сама по себе имеет тип,'a -> unit
где'a
обозначает произвольный тип, поэтому в контексте нашего условного выражения, обеспечивающегоstring -> unit
тип, это будет работать. (Переменная типа'a
создается с помощью типаstring
.) Однако в этом случае мы не будем ничего печатать, так как анонимная функция никогда не вызывается! Помните, что когда мы заходим вthen
-part, общий код таков"<code>"<code>
, что<code>
-part оценивает функцию, но, поскольку после нее ничего не происходит, она не вызывается.Вместо этого мы используем секвенизацию, которая имеет вид
(<exp_1>; ...; <exp_n>)
где<exp_1>
к<exp_n-1>
может иметь произвольные типы и тип<exp_n>
обеспечивает тип всей sequentialisation. С функциональной точки зрения значения<exp_1>
to<exp_n-1>
просто отбрасываются, однако SML также поддерживает императивные конструкции, поэтому выражения могут иметь побочные эффекты. Короче говоря, мы принимаем(print(it^it);print)
в качествеthen
-part, печатая сначала, а затем возвращая функциюprint
правильного типа.источник
В ,
27, 23 байтаПопробуйте онлайн!
Так как он содержит некоторые непечатаемые символы, вот читаемая версия:
и вот hexdump:
Итак, самое первое, что нам нужно сделать, это определить, является ли первый символ кавычкой.
éP
вставляет символ «P», но"éP
является NOOP. После этого мы запускаем небольшую модификацию стандартного расширяемого квайна, а именно:Мы собираемся сделать это немного по-другому, хотя. Прежде всего нам нужно вставить начальный текст «éP». Итак, мы делаем
Вот где происходит ветвление. Текст в буфере сейчас
Если бы мы не заключили его в кавычки, в этом случае 'P' никогда бы не был вставлен, а буфер:
Поскольку мы все еще записываем, мы можем делать все, что захотим, и он будет добавлен в буфер, когда это
"qp
произойдет. Отсюда довольно легко условно удалить кавычки:источник
JavaScript (ES6),
239237 байтСтарайтесь пробовать каждую версию в новой среде (например, в новой вкладке браузера)
Должен быть хотя бы один способ упростить это ...
источник