Цитаты-безопасные Quines


17

Ваша задача проста: написать программу (или функцию), которая не требует ввода и выводит (или возвращает) свой исходный код. Подвох заключается в том, что когда программа обернута "quotes"(символ Unicode 34), она должна снова вывести свой (теперь заключенный в кавычки) исходный код.

Стандартные правила для Quines применяются. Это , поэтому выигрывает самая короткая (в байтах) программа.


8
@ATaco мыслить творчески. Код в кавычках , как правило , не выполняется, но когда вся программа окружена кавычками эти разделы будут выполнены.
Павел

1
Хм, хорошая мысль.
ATaco

Это может работать с BF на реализациях, которые поддерживают !...
Esolanging Fruit

1
Вы должны использовать "? Некоторые языки поддерживают два или три символа кавычки.
Нил

1
@tkellehe Meta: Что считается правильной формой? Насколько я понимаю, ваша 1-байтовая квинна нарушает требования к коду / данным, сформулированные в посте с наибольшим количеством голосов.
Лайкони

Ответы:


4

Noodel , 9 7 байтов

Эта версия работает так же, как и другая, просто я забыл, что у Нуделя есть способ запустить блок кода один раз, и я создал язык ...

Ḷ1ḥ-Ð1ḥ@€

ḷḥ-Ðḥ@ḅ

Попытайся:)


Как это устроено

ḷḥ-Ðḥ@ḅ # Single statement that builds itself as a string.
ḷ       # Loop the following block of code unconditionally.
 ḥ-     # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
   Ð    # Push the stack as an array to stdout (since is an array it is done by reference).
    ḥ@  # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
      ḅ # Break out of the given loop. (The stack is now ["ḷ", "ḥ-Ðḥ@ḅ"]).

        # The top of the stack is popped off and displayed which modifies the array to produce {["ḷ"], "ḥ-Ðḥ@ḅ"} in stdout.

Quote-безопасности

Размещение "символа до и после программы работает, потому что у Noodel есть набор символов, посвященных тому, что я называю печатными . Они сразу же разбираются как строковые литералы, когда помещаются сами по себе и позволяют легко распечатать что-то на экране. Так что в отличие от большинства языков, Нудель видит нормальный набор ASCII, который считается достойным печати, как прямые строковые литералы (за исключением пробелов и перевода строки), в которых цитирование кода просто рассматривается как нажатие на строки.

"ḷḥ-Ðḥ@ḅ"

"         # Pushes on the string literal "\"" onto the stack.

 ḷḥ-Ðḥ@ḅ  # Same execution as before, simply builds the Quine for this loop.
 ḷ        # Loop the following block of code unconditionally.
  ḥ-      # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
    Ð     # Push the stack as an array to stdout (since is an array it is done by reference).
     ḥ@   # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
       ḅ  # Break out of the given loop. (The stack is now ["\"", "ḷ", "ḥ-Ðḥ@ḅ"]).

        " # Pushes on the string literal "\"" onto the stack.

          # The top of the stack is popped off and displayed which modifies the array to produce {["\"", "ḷ", "ḥ-Ðḥ@ḅ"], "\""} in stdout.

"Попытайся:)"


обрывки

<div id="noodel" code='ḷḥ-Ðḥ@ḅ' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


<div id="noodel" code='"ḷḥ-Ðḥ@ḅ"' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


Я не думаю, что использование eявляется действительным. Вопрос не о символе, закодированном как байт 34, а о "
Денис

@ Денис, я предполагаю, что вы говорите, что ссылка на символ Unicode 34 была просто для того, чтобы все использовали одно и то же "? (Извините, просто пытаюсь убедиться, что я понимаю, что вы говорите) Кроме того, я должен удалить весь текст в ответе, касающемся использования e?
tkellehe

1
Да, есть тысячи кодировок, но только один набор символов Unicode. Поскольку "работает, я бы просто удалил обсуждение и просто использовал ".
Деннис

11

Python 2 3, 181 152 130 124 122 байта

""" """>" "or exec("oct=0");p='"""" """>" "or exec("oct=0");p=%r;a=oct==0;print(p[a:~a]%%p)#".';a=oct==0;print(p[a:~a]%p)#

Попробуйте онлайн! TIO поставляется с верхним и нижним колонтитулами, которые автоматически проверяют действительность квин. Вы можете очистить их, чтобы просто запустить Quine.

Этот код работает с использованием строк в тройных кавычках в Python. """ """равно' ' и """" """равно '" '.

Код использует exec , но не для «не-quiney», способ выполнения данных в виде кода, просто для установки переменной внутри выражения. execПравильно закодированы в данных, тоже.

Первое утверждение сравнивает строку, возможно с кавычкой, до " " , и устанавливает переменную octсоответственно. (Переменная могла быть любой короткой встроенной.)

Остальная часть кода затем реализует традиционную Python quine, используя %r форматирование строк, с некоторым дополнительным кодом, который удаляет лишние кавычки, еслиoct не изменены.

Альтернативная версия, использующая читерство, execимеет размер 126 байт с менее повторяющимся кодом:

""" """>" "and exec("oct=0");s='"""" """>" "and exec("oct=0");s=%r;p=%r;exec(p)#".';p='a=oct!=0;print(s[a:~a]%(s,p))';exec(p)#

Попробуйте онлайн!


7

StandardML , 182 176 108 байт

";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))

Версия без кавычек: попробуйте это на codingground.
Цитируемая версия: попробуйте на codingground.

Обратите внимание, что вывод выглядит примерно так

> val it = "{some string}" : string
> val it = "{some string}" : string
{output to stdout}> val it = fn : string -> unit

потому что код интерпретируется декларацией по декларации (каждая ;заканчивается декларацией) и показывает значение и тип каждой декларации.


Фон

В SML есть формула вида <code>"<code in quotes>":

str(chr 34);(fn x=>print(x^it^x^it))"str(chr 34);(fn x=>print(x^it^x^it))" 

и один в форме "<code in quotes>"<code>:

";str(chr 34)^it;print(it^it)";str(chr 34)^it;print(it^it)

Оба полагаются на тот факт, что <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>качестве аргумента и, следовательно, должны быть функцией, которая обрабатывает такой аргумент.

(if size it>1then(print(it^it);fn _=>())else fn x=>print(it^it^x^it^x^it))

Чтобы определить, в каком случае мы находимся, мы проверяем, больше ли размер 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правильного типа.


7

В , 27 , 23 байта

éPñi"éP241"qpá"lxx|xÿ

Попробуйте онлайн!

Так как он содержит некоторые непечатаемые символы, вот читаемая версия:

éPñi"éP<C-v>241<esc>"qpá"lxx|xÿ

и вот hexdump:

00000000: e950 f169 22e9 5016 3234 311b 2271 70e1  .P.i".P.241."qp.
00000010: 226c 7878 7c78 ff                        "lxx|x.

Итак, самое первое, что нам нужно сделать, это определить, является ли первый символ кавычкой. éPвставляет символ «P», но"éP является NOOP. После этого мы запускаем небольшую модификацию стандартного расширяемого квайна, а именно:

ñi<C-v>241<esc>"qpÿ

Мы собираемся сделать это немного по-другому, хотя. Прежде всего нам нужно вставить начальный текст «éP». Итак, мы делаем

ñ                        " Start recording into register 'q'
 i                       " Enter insert mode
  "éP<C-v>241<esc>       " Enter the following text: '"éPñ'
                  "qp    " Paste the text in register 'q'
                     á"  " Append a '"'

Вот где происходит ветвление. Текст в буфере сейчас

"éPñi"éP<C-v>241<esc>"qpá"P
Cursor is here ----------^

Если бы мы не заключили его в кавычки, в этом случае 'P' никогда бы не был вставлен, а буфер:

"éPñi"éP<C-v>241<esc>"qpá"
Cursor is here ----------^

Поскольку мы все еще записываем, мы можем делать все, что захотим, и он будет добавлен в буфер, когда это "qpпроизойдет. Отсюда довольно легко условно удалить кавычки:

l           " Move one character to the right. If there is no character to the right, 
            " then this is effectively a "break" statement, stopping playback of the recording
 xx         " Delete two characters (the '"P')
   |        " Move to the first character on this line
    x       " Delete one character
     ÿ      " End the program

3

JavaScript (ES6), 239 237 байт

Set=``;eval(";a='Set=``;eval(~;a=1;S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);~)';S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);")

Старайтесь пробовать каждую версию в новой среде (например, в новой вкладке браузера)

Должен быть хотя бы один способ упростить это ...


1
Я полагаю, вы могли бы использовать массив для замены следующим образом: [x = "replace"]. Хотя, возможно, что-то сломается, я не очень разбираюсь в муках ...
Луки
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.