Quote-Safe Quines


17

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

Діють стандартні правила для ласощів. Це , тому найкоротша програма (в байтах) виграє.


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

1
Хм, хороший пункт.
Атако

Це може працювати з BF над реалізаціями, які підтримують !...
Esolanging Fruit

1
Ви повинні використовувати "? Деякі мови підтримують два-три символи цитати.
Ніл

1
@tkellehe Meta: Що вважається належною квіточкою? Наскільки я розумію вашу 1-байтну квітку, вона порушує вимогу коду / даних, сформульованої у найвищому голосуванні.
Лайконі

Відповіді:


4

Нуд , 9 7 байт

Ця версія працює так само, як і інша, тільки що я забув, що у Noodel є спосіб запустити блок коду один раз, і я зробив мову ...

Ḷ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.

Цитата-Безпека

Розміщення "персонажа до і після програми працює тому, що у Noodel є набір символів, присвячений тому, що я називаю для друку . Вони негайно розбираються як літеральні рядки, коли розміщуються самі, і дозволяють легко надрукувати щось на екрані. Отже, на відміну від більшості мов, 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. Незалежно від того, яке кодування ви використовуєте, є лише одне:"
Dennis

@Dennis, я здогадуюсь, що ви говорите, що посилання на символ 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, але не для "не-квінейського" способу виконання даних як коду, лише для встановлення змінної зсередини виразу. Ці дані execтакож правильно закодовані.

Перше твердження порівнює рядок, можливо, з попередньою цитатою, до " "та відповідно встановлює змінну oct. (Ця змінна могла бути будь-якою короткою вбудованою.)

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

Альтернативна версія, що використовує "cheaty", 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))

Версія без котирування : Спробуйте це на кодування.
Версія, що цитується: Спробуйте на кодування.

Зауважте, що результат виглядає приблизно так

> 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який використовується, коли в декларації не вказано явного ідентифікатора.

У першому quine 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-байтна версія, однак ви також можете зрозуміти її, прочитавши це пояснення.

Квітна безпечна квітка поєднує в собі обидва вищезазначені підходи і є самою формою "<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і просто виконуємо 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 оцінює функцію, але, оскільки після неї нічого не відбувається, його не викликають.

Замість цього ми використовуємо sequentialisation , яка має вигляд , (<exp_1>; ...; <exp_n>)де <exp_1>до <exp_n-1>може мати довільні типи і тип <exp_n>забезпечує тип всієї sequentialisation. З функціональної точки зору значення <exp_1>для <exp_n-1>просто відкидається, однак SML також підтримує імперативні конструкції , так що вираження можуть мати побічні ефекти. Коротше кажучи, ми беремо (print(it^it);print)як then-part, таким чином спочатку друкуємо, а потім повертаємо функцію, printщо має правильний тип.


7

V , 27 , 23 байти

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

Спробуйте в Інтернеті!

Оскільки в ньому є кілька недрукованих символів, ось читабельна версія:

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

і ось шестикутник:

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 = "заміна"]. Хоча я можу зламати речі, я не дуже досвідчений з королевами ...
Лука
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.