Есть много проблем, которые говорят «интерпретировать X», где X - простой язык. На мой взгляд, это слишком скучно. Чтобы дать всем откладывающим людям в Интернете что-то интересное, вы можете попытаться сделать это:
Вызов
Выберите язык $LANG
. $LANG
может быть любым полным языком программирования Тьюринга или полным подмножеством языка программирования Тьюринга. Помните, что если вы опускаете функцию вашего языка $LANG
для устного перевода, вы не должны использовать ее и для своей собственной программы, поскольку ваша заявка также должна быть записана $LANG
.
Написать компилятор / интерпретатор для $LANG
написанного в $LANG
. Вы можете использовать все возможности (в том числе eval
и друзей) вашего языка, которые доступны для написания этого компилятора. Чтобы сделать задачу более сложной, есть одно ограничение: $LANG
ваша программа должна иметь возможность интерпретировать / компилировать все допустимые программы, кроме самого вашего интерпретатора / компилятора. Если выяснится, что интерпретируемая / компилируемая программа является вашим интерпретатором или самим компилятором (независимо от имени файла), ваша программа должна сделать что-то совершенно не связанное с функциональностью интерпретатора или компилятора (например, перебор или печать Hello, world!
).
Чтобы сделать эту задачу еще более сложной, ваша программа не должна читать свой собственный источник при компиляции или интерпретации.
Характеристики
- Эта задача - код гольф. Представление с наименьшим количеством правильных символов выигрывает. В случае ничьей первое решение выигрывает.
- Ваша программа / скрипт должен читать программу, которую нужно интерпретировать из файла. Вы можете жестко указать его путь и имя. Когда файл читается, вы можете скомпилировать файл в другой файл (который должен быть исполняемым в вашей системе) или запустить его напрямую. Если вам
$LANG
не хватает возможностей чтения файлов, вы можете выбрать другой способ чтения в подходящем коде$LANG
. Вы не можете выбрать$LANG
в качестве подмножества другой язык, но с удаленными возможностями чтения файлов. - Применяются обычные правила игры в гольф. То есть: ваш личный язык домашнего питомца, который вы создали для решения этой задачи, запрещен, если решение становится тривиальным с его использованием (например, определение программы с одним символом, которая точно реализует решение). Нарушение правил приветствуется.
источник
Ответы:
Руби, 63
источник
Perl, 89 символов, без обмана
Обратите внимание, что этот код очень требователен к тому, что считается «собой». В частности, он не будет распознавать себя, если на входе есть какие-либо завершающие символы новой строки или другие лишние пробелы. Чтобы проверить это, сохраните его в файл с именем (например)
unquine.pl
и сделайте это:Помните, что
unquine.pl
файл должен быть ровно 89 байт, не больше, не меньше. Запуск его с другим скриптом Perl в качестве ввода просто выполняет другой скрипт, как и должно:Как следует из названия, реализация основана на квине, а именно:
Этот код устанавливает
$_
равный себе; остальная часть программы (которая, конечно, должна быть продублирована внутри$_
) просто сравнивается$_
с вводом, умирает, если они совпадают, и оценивает ввод в противном случае.источник
&&
/;
пару на троичную (один символ выключен, удвоенный путем кавычек). Отличная идея и реализация!GolfScript, 30 символов
Эта программа читает содержимое файла, названного в командной строке, и, если он не совсем совпадает с приведенным выше кодом, интерпретирует его как GolfScript. Если ввод в точности равен приведенному выше коду, он будет просто напечатан без изменений (за исключением новой строки, добавленной в конец).
Это довольно простая адаптация этой самоидентифицирующейся программы . В частности:
{ }
является литералом блока кода в GolfScript..~
, применяется к блоку кода, дублирует блок и выполняет копию.Внутри блока кода:
`
переводит в строку копию блока кода.".~"+
добавляет символы.~
к нему, получая строку, содержащую исходный код программы."#{$<.read}"
это документально хак , который позволяет выполнение кода Ruby , в пределах GolfScript. В этом случае он выполняет оператор Ruby$<.read
(бессовестно украденный из решения Ruby от Lowjacker's ), который читает и возвращает содержимое любых файлов, указанных в командной строке. Этот взлом необходим, потому что сам GolfScript не предоставляет явных возможностей ввода / вывода файлов..@
дублирует и перемешивает элементы в верхней части стека, так что в стеке содержатся две копии содержимого файла, за которым следует исходный код этой программы.=!
сравнивает два верхних элемента в стеке (т. е. содержимое файла и источник), возвращая 1, если они разные, и 0, если они одинаковые.{~}*
оценивает оставшуюся копию содержимого файла как код GolfScript, но только если результат сравнения равен 1. (Технически, он выполняет блок кода{~}
столько раз, сколько задано числом в стеке, то есть 0 или 1 раз. Внутри блок,~
является оператором eval GolfScript.)Ps. Если чтение кода для выполнения из stdin разрешено, эта задача может быть решена с помощью 21 символа без необходимости использовать Ruby:
Эта программа будет читать входную строку из stdin и, если она не соответствует своему собственному источнику, выполняет ее (с пустым вводом). Как и в приведенной выше программе, ввод, который соответствует источнику, просто возвращается обратно.
источник
Python,
167130118 байтЭто моя первая попытка игры в гольф, так что здесь идет! Он интерпретирует любую программу, кроме себя
Улучшенная версия:
Если он получит себя сам, то он возмущается:
Я думаю, что это решение работает почти так же, как и у Ильмари Каронена, основная идея примерно такая:
Куина, которую я использовал, была основана на этом:
Но с тех пор я понял, что намного короче
И это может быть еще короче, если вы разрешите интерактивную оболочку Python, и в этом случае вы можете сделать:
Поскольку у python нет короткого способа получить аргументы командной строки, я выбрал raw_input () (который все еще довольно длинный, но не такой длинный, как
Использование это:
или
Я нашел более короткую форму для использования, но вот моя старая версия (для потомков):
источник
Я не могу точно прочитать из файла, используя Javascript (хорошо, я мог бы, используя HTML5 FileReader, но это делает вещи намного сложнее, чем мне нужно). Итак, это функция, которая принимает программу Javascript в виде строки и запускает ее.
Это, вероятно, не так играется в гольф, как могло бы быть, но здесь это в любом случае:
Javascript, 252
Дайте мне знать, если кто-нибудь знает лучшую технику для формирования Quine в Javascript.
источник
45 символов sh (оболочка POSIX). Код для запуска должен быть в файле
./c
.Код для самого интерпретатора должен быть в файле
./p
, так что я думаю, что меня обманули, хотя задача, похоже, не запрещает этого. Или это лишит меня права на «язык» как «язык программирования, полный по Тьюрингу»?Используя инструмент, который обычно является внешним исполняемым файлом, но теоретически может быть встроен в оболочку, код можно сократить:
Это 18 символов, и
-s
бит просто для того, чтобы подавить строку, которая в противном случае всегда выводилась бы для допустимых (не-self) программ.И тогда вы всегда можете создать версию языка оболочки, которая выполняет вышеизложенное с более кратким синтаксисом.
И тогда вы всегда можете создать программу, которая, когда вход состоит из одного '.' - или, черт возьми, пустая строка - оценивает содержимое другого файла как обычный код и называет это языком программирования. Таким образом, пустая строка будет вашим решением проблемы на языке, который вы создали. На самом деле, вот переводчик для такого языка:
Используя язык, который интерпретирует приведенный выше скрипт, решением является пустая строка. И местоположение кода больше не нужно жестко кодировать.
Проблема?
источник
./othercode
) и выполняет ничего, когда код является пустой строкой. Я не должен был называть файл ./othercode, это вводит в заблуждение; это просто код, который интерпретатор, написанный на языке пустых строк, будет интерпретировать.JavaScript, 135 символов
JavaScript-решение Питера Олсона вдохновило меня на попытку перенести моё Perl-решение на JS. Как и его решение, этот код определяет функцию,
c
которая принимает строку и обрабатывает ее, если она не равна приведенному выше коду.Это мне потребовалось некоторое время , чтобы выяснить , хороший способ справиться с отсутствием сбалансированных разделителей строк в JavaScript, пока я не нашел , что задним числом является очевидным решением:
unescape()
.Удобно, что мой код не содержит обратной косой черты или двойных кавычек, поэтому его можно безопасно хранить в двойных кавычках. Это облегчает тестирование:
источник
alert()
с ,0
чтобы сделать это ничего не делать вместо того , чтобы предупреждатьundefined
и сохранить 13 символов.p=>...
вместоfunction c(p)
Common Lisp, 59
sbcl --load
)L
, которая может компилировать файлы Common Lisp(L <your file>)
, при чтении файла выдается сообщение об ошибке .Зачем?
Потому что в первый раз вы вставили
:~
ключевое слово в*features*
. Теперь ваша среда знает об этой~
функции, и макрос считывателя#+
, после оценки~
выражения функции , преуспеет и прочитает следующую форму вместо того, чтобы пропустить ее, как это было в первый раз. В вашем файле следующая форма#.(#:a)
, которая просит оценить(#:a)
во время чтения и использовать полученное значение в качестве читаемого кода. Но(#:a)
вызывает функцию, связанную с неинтернизированным символом#:a
. Так как он не#:a
является внутренним, он является новым символом, который не привязан ни к какой функции (т.е. нетfboundp
). Ошибка.источник
Схема, 48 или 51 символов
Схема - это язык с множеством различных реализаций. Несмотря на то, что реализации должны соответствовать последнему RnRS, последний рабочий стандарт (R6RS) был непопулярным из-за отсутствия минимализма. Скоро R7RS будет выпущен в качестве исправления, разделив язык на 2. Первый язык - мощный и минималистичный, а второй - расширенный набор первых, предназначенный для предоставления расширений функций для взаимодействия между реализациями. До тех пор мы полагаемся на SRFI (запросы схемы для реализации), которые обеспечивают (если реализовано в реализации хоста или вручную (как это обычно бывает в схеме)) средство для переносимого выполнения общих задач. Все это говорит о том, что первый фрагмент кода (51 символ), хотя и остается настолько переносимым, насколько это возможно, использует SRFI-22 (выполнение сценариев схемы в UNIX) для доступа к аргументам командной строки:
или более наглядно:
Второй (48 символов) - это средство интерпретации, не содержащее файлов, которое не может оценить себя (в нулевой среде):
или более наглядно:
источник
Groovy, 13 байт
Это должно интерпретировать подмножество Groovy.
контрольные примеры:
К сожалению, несмотря на то, что он, безусловно, раздражает, он делает это полностью аналогично интерпретатору и делает это для довольно большого вклада.
источник
Javascript ES6, 45 байт
Все еще конкурентоспособны! (THX @ Downgoat)
источник