Ошибка (или предупреждение) quine, это также обычный quine [закрыто]

9

(Вдохновлен этим комментарием на старый вопрос.)

Фон

Куайн ошибки (также известный как «Kimian Куайны») представляет собой программу , которая при компиляции или запуска, вызывает компилятор / интерпретатор / среда для вывода сообщения об ошибке , которое имеет идентичный текст самой программы, и ничего больше. Для целей этой задачи мы широко определяем «ошибку», чтобы включить и предупреждения.

задача

В этом вызове мы ищем что также является ошибкой. При выполнении программа должна нормально печатать свой собственный исходный код (т. Е. Не как сообщение об ошибке / предупреждение); это должен быть правильный quine (т. е. некоторая часть программы должна кодировать другую часть вывода). Кроме того, компиляция и выполнение программы должны также приводить к тому, что исходный код программы - и ничто иное - будет напечатано реализацией в виде сообщений об ошибках или предупреждений. (Обратите внимание, что это означает, что вы не сможете использовать ошибки времени компиляции на языках, где они не позволяют программе нормально работать.) Другими словами, исходный код программы будет напечатан дважды, один раз через каждый метод.

Разъяснения

  • В большинстве случаев будет очевидно, что является и не является сообщением об ошибке / предупреждением; мы не делаем различий между ними здесь. В неоднозначных случаях определите сообщение об ошибке / предупреждение как любой текст, который выводится реализацией: 1. как следствие чего-то другого, кроме выполнения команды (или любого другого наиболее близкого эквивалента в языке); или 2. это не было частью ввода в команду, которая произвела его как вывод.
  • Часть ошибки / предупреждения в квине не обязательно должна быть правильной (хотя в большинстве случаев это будет случайно, так как большинство сообщений об ошибках и предупреждениях содержат значительное количество фиксированного текста).
  • Допустимо, чтобы программа выводила несколько ошибок / предупреждений, которые образуют источник программы при объединении. Недопустимо выводить ошибки / предупреждения, которые не отображаются в источнике.
  • В отличие от многих задач, переключатели, передаваемые компилятору, и имя файла программы, вероятно, будут иметь большое значение в этой задаче. Учитывая, что в противном случае задача может быть невозможной, я готов проявить гибкость, хотя, если вы запускаете реализацию необычным образом, помните, что правила PPCG взимают за это штраф в байтах (равный числу дополнительных символов, которые вам нужно добавить в командной строке самый короткий «нормальный» способ запуска программы), и, таким образом, вам нужно будет указать размер штрафа в своем посте. (Например, если используемый вами интерпретатор читает программу из файла и не имеет особых ограничений на имя файла, самый короткий нормальный способ запуска программы - это файл с 1-символьным именем файла; таким образом,
  • Версия компилятора / интерпретатора, которую вы используете, вполне может иметь значение, поэтому в качестве части вашего представления, пожалуйста, укажите конкретный компилятор или интерпретатор, на котором работает ваша программа, и какая версия требуется. (Например, в представлении C может быть указано «C (gcc 6.2.0)» в заголовке.)
  • Обратите внимание, что эта задача может быть недоступна на всех языках. В тех языках, где это возможно, самый простой способ, вероятно, состоит в том, чтобы найти сообщение об ошибке или предупреждение, для которого можно настроить некоторое подмножество текста (путем изменения имени чего-то, что указывается в сообщении; имена файлов - это общий выбор здесь, но не единственный). Я буду особенно впечатлен (и удивлен), если кто-то найдет способ сделать это, используя только сообщения об ошибках и предупреждения, текст которых зафиксирован.

Состояние победы

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

Сообщество
источник
2
Как я сказал в чате, я думаю, что первый пункт пули неясен. В большинстве случаев будет очевидно, что сообщение об ошибке / предупреждении является и не является просто отправной точкой для дискуссий и языковой адвокатуры.
Деннис
@Dennis: я согласен в принципе, что ситуация не велика, но с другой стороны не могу придумать конкретный способ ее улучшить; удаление исключения для вещей, которые, очевидно, являются сообщениями об ошибках, может привести к некоторым непреднамеренным ситуациям на некоторых языках, что может привести к большему ущербу, чем лечит; если вы думаете, что можете улучшить вопрос, у меня нет возражений против его редактирования (и я не думаю, что вопросы по PPCG должны иметь «владение» в любом случае, хотя это другая проблема)
На самом деле, я думаю, что вопрос неясен и не имеет объективного критерия достоверности. Я согласен, что мое предлагаемое изменение может сделать еще хуже. Один из возможных вариантов действий - отложить вызов и поместить его в песочницу.
Деннис
1
Сейчас я отложил вызов. Я надеюсь, что вы пересмотрите репост в песочнице. Это очень интересная идея, и было бы стыдно оставить ее напрасной.
Деннис
1
Песочница пост здесь . (Я думал об изменении этого вопроса, но это поместило бы сообщение в очередь повторного открытия, что было бы крайне контрпродуктивно, так как затруднило бы повторное открытие, если и когда проблемы будут решены.)

Ответы:

9

JavaScript (Firefox 50), 153 байта

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})

объяснение

Идея здесь состояла в том, чтобы начать с самой легко изменяемой квайны JS, которую я нашел:

".replace(/.+/,x=>alert(uneval(x)+x))".replace(/.+/,x=>alert(uneval(x)+x))

throwКлючевое слово является простым способом сделать это бросить свой собственный код , а также:

".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})

Однако есть небольшая проблема: Firefox добавляет к выброшенному сообщению Error:. К счастью, Error: mycodeэто действительно правильный JavaScript! (Чтобы узнать больше об этом, посетите MDN .)

Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})

К сожалению, это предупреждает не ту вещь:

".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: 

Поскольку кавычка больше не находится в начале кода, uneval(x)+xэто не даст нам правильный результат. Лучший способ исправить это - добавить заполнитель вместо вложенной строки:

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x})

О-о, теперь Error:в сообщении об ошибке есть дополнительная информация . Давайте исправим это, разрезав строку:

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})

И наконец, и вывод, и сообщение об ошибке идентичны коду! Я бы добавил фрагмент стека, но, похоже, он не работает во всех браузерах.

ETHproductions
источник
5

Python 2, 217 80 51 байт

Конечный перевод строки обязателен.

s='s=%r;print s%%s;exit(s%%s)';print s%s;exit(s%s)

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

Я начал с простого quine:

s='s=%r;print s%%s';print s%s

Затем я добавил raiseна конце, чтобы бросить IOError.

s='s=%r;print s%%s;raise IOError(s%%s)';print s%s;raise IOError(s%s)

К сожалению, обратная трассировка вызывала проблемы (я не мог заставить ее полностью исчезнуть), и имя исключения всегда печаталось впереди IOError: <code here>, даже если я удалял трассировку.

Затем я нашел этот полезный ответ SO и изменил его для моих целей.

Затем я обнаружил, что могу пропустить создание своего собственного класса и просто использовать sys.exit, делая мой код намного короче.

mbomb007
источник
1
Я не думаю, что это соответствует определению ошибки в спецификации вызова, поскольку это не является следствием чего-то другого, кроме выполнения команды, и не было частью ввода команды, которая выдает его в качестве вывода . Тем не менее, равнина exitработает просто отлично здесь. Нет необходимости sys.
Деннис