Гольф Фиолетовый Переводчик
Фиолетовый - это esolang, который предназначен для двух основных целей:
- Чтобы минимизировать баклажаны , так как не хватает самоизменяющихся языков с одной инструкцией.
- Чтобы допустить возможность ужасно маленьких переводчиков гольфа. Мой первый проход к достаточно полнофункциональному интерпретатору Python 2 составляет всего 702 байта, и я уверен, что более опытный игрок в гольф мог бы от этого немного избавиться.
Ваша цель - написать переводчика для этого языка.
Информация о Purple:
Программа Purple - это последовательность символов, помещенная в бесконечный, адресуемый массив памяти, так что первый символ программы помещается в нулевой адрес. Остальная часть массива (как до, так и после того места, где хранится программа Purple) инициализируется нулем.
В Purple есть три регистра, называемых a и b и i , каждый из которых может содержать целое число со знаком и инициализируется нулем. Я также указатель инструкции и всегда указывает на текущую выполняющуюся инструкцию Purple.
В каждом цикле интерпретатор считывает последовательность из трех смежных символов, начиная с ячейки памяти, указанной указателем команды, и пытается выполнить эту последовательность как инструкцию Purple. После этого указатель инструкции всегда увеличивается на 3.
Синтаксически инструкция Purple состоит из трех символов (или их кодировок) в строке, например « xyz ».
Первый символ x может быть любым из следующих:
abABio
Эти символы имеют следующее значение:
a - Place the result in register a.
b - Place the result in register b.
A - Place the result in the location in memory referred to by register a.
B - Place the result in the location in memory referred to by register b.
i - Set the instruction pointer to the result.
o - Output the result to stdout.
Два других байта y и z могут быть любыми из следующих:
abABio1
Каждый из этих символов имеет следующее значение:
a - Return the contents of register a.
b - Return the contents of register b.
A - Return the contents of the memory array at the address stored in register a.
B - Return the contents of the memory array at the address stored in register b.
i - Return the contents of register i (the instruction pointer).
o - Return the value of a single character read from stdin.
1 - Return the literal numeric value 1.
После извлечения инструкции интерпретатор Purple вычислит y, а затем z , вычтет результат z из результата y , а затем выполнит действие, обозначенное x на разнице.
Если последовательность из трех символов (или их кодировка) не является допустимой инструкцией Purple, интерпретатор немедленно останавливается без каких-либо ошибок.
Ваш переводчик должен:
- Будьте полной программой, а не функцией.
- Никогда не выводите в stderr, если EOF не читается .
- Вести себя аналогично эталонной реализации на всех правильно сформированных входах, которые не содержат очень больших чисел, включая тестовые программы, приведенные ниже. (Ну, точно так же, как по времени - он может работать медленнее, но не слишком сильно!)
Вы можете предоставить программу интерпретатору в любой форме: прочитать ее из файла, вставить в программу в виде строки или прочитать из stdin.
Тестовые случаи:
Программа
ooo
при запуске с вводом
z!
должен уступить
Y
Программа
bbboobiii
при запуске с вводом
It's a cat program.
(или любой другой вход) должен дать
It's a cat program.
(или любой другой вход, который он получил), а затем начните сначала и сделайте то же самое снова .
Программа
Aoab11bi1bABoAaiba
при запуске с вводом
0
должен уступить
0
а затем остановить, но при запуске с вводом
1
следует продолжить вывод
1
навсегда.
Программа
b1bbb1oAbabaa1ab1Ab1Bi1b
должен уступить
b1bbb1oAbabaa1ab1Ab1Bi1b
Программа
aA1aa1bb1oAbbi1bb1bbAb1Bi1b Purple is the awesomest! Why haven't you tried it yet?
!dlroW ,olleG
должен уступить
Hello, World!
Подсчет очков:
Это код-гольф , поэтому выигрывает самый короткий источник в байтах, который может быть изменен следующим бонусом.
Бонус:
- -10%, если ваш интерпретатор читает имя файла из stdin или из аргумента командной строки и загружает программу из файла.
источник
uint32
для символов и MAXINT для целыхОтветы:
Pyth,
148128121 байт (или 124 * .9 = 111,6, см. Внизу)Тестирование
Код, указанный в первой строке STDIN, ввод в программу Purple для остальной части STDIN. Чтобы использовать код с символами новой строки, используйте альтернативную версию внизу.
Разумно в гольф. Вот это с разрывами строки и отступами для ясности:
По сути,
#
цикл выполняет выполнение и останавливается из-за ошибки.a
иb
объединены в одну переменнуюJ
.Z
указатель инструкцииk
является входом в программу Purple.H
это лента, представленная в виде словаря.b
текущий результатY
текущий первый байт инструкции.Чтение из файла:
Дайте имя файла в качестве первой строки STDIN. Тестовый забег:
источник
JavaScript (ES6), 292 байта
объяснение
Ответы JavaScript всегда странные, когда
STDIN
иSTDOUT
требуются ...Первая подсказка является вводом для строки программы. Каждая подсказка, которая следует из
o
инструкции, будет читать только первый символ.eval
используется для замены обычной фразы, которая сохраняет несколько байтов. Развернутый и безeval
программы выглядит так:источник
c="charCodeAt"
ли заменить второе простоc
?array[-1] = 1
так же, какarray = { "-1": 1 }
. Оба могут быть доступны сarray[-1]
.Цейлон,
827792671 байтОн ведет себя немного иначе, чем эталонная реализация, когда программа пытается прочитать ввод в EOF - эталонная реализация аварийно завершается с помощью TypeError, что слишком дорого для воспроизведения здесь (а также, вероятно, с ошибкой), поэтому вместо этого будет возвращаться -1 ( повторно, при необходимости).
(При попытке записать это значение -1 в стандартный вывод интерпретатор завершит работу с OverflowError. Аналогичное произойдет, если будет выведено целое число вне диапазона Unicode.)
Интерпретатор воспринимает программу в качестве первого аргумента командной строки (не забудьте указать ее для вашей оболочки, если она содержит пробелы или другие интересные вещи).
В Цейлоне мы можем легко читать ввод только построчно (я думаю, это изменится в одной из следующих версий), поэтому, когда
o
используется для чтения, я читаю целую строку и буферизую части для будущего использования. Я думаю, что это работает аналогично в реализации Python при подключении к терминалу.При попытке выполнить команду (часть), которая не является одним из допустимых символов,
nothing
будет вызываться ошибка AssertionError, которую мы затем перехватываем в блоке catch вокруг основного цикла.Я думаю, что это, предпочтительно, должен быть пользовательский тип Exception (так как AssertionError может также возникнуть в других местах, если у меня есть ошибка), но это заняло бы гораздо больше места, съедая большинство улучшений, которые я сделал с первой версии.
Некоторые трюки, используемые для игры в гольф:
map
функцией, и каждый раз создаем новуюA
илиB
используемую как x .variable
аннотацию, которая есть сейчасl
).E
(для среды) иs
метода (шага) - теперь все происходит внутриrun
функции..integer
для получения кодовой точки символа,.hash
дает тот же результат. Такимstring*.hash
же образом, какstring.map(Character.integer)
(дает итеративный из кодовых точек из строки).is I ...
он короче, чемexists ...
.x
в строку)"``t``"
оно корочеt.string
(или того, что я использовал для символаString{t}
).Вот отформатированная (и закомментированная) версия:
источник