99 (произносится как «девяносто девять») - это совершенно новый язык эзотерического программирования (не путать с 99 , обратите внимание на курсив). Ваша задача в этой задаче - написать переводчика для 99, который будет максимально коротким. Представление с наименьшим количеством байтов выигрывает. Tiebreaker переходит к представлению, опубликованному первым.
Поскольку этот вопрос немного глубже, чем обычно, и мне не терпится увидеть хорошие ответы, я буду награждать награду в 250 представителей своим любимым ответом (не обязательно победителем).
99 Спец
99 - императивный язык. Каждая строка в программе 99 представляет собой один оператор , и во время выполнения указатель инструкции начинается с верхней строки и проходит по порядку через каждую из последующих строк, выполняя их по пути. Программа заканчивается, когда последняя строка была выполнена. Операторы Goto могут перенаправлять путь указателя инструкции.
Новая строка, пробел и 9
единственные три символа, которые имеют значение в программе 99 . Все остальные персонажи полностью игнорируются. Кроме того, завершающие пробелы в каждой строке игнорируются, и несколько пробелов в строке читаются как один пробел. («Новая строка » относится к любой обычной кодировке разрыва строки . Не имеет значения, какой из них использует ваш интерпретатор.)
Итак, эта программа:
9 BLAH 99 9a9bb9c9
9 this line and the next have 6 trailing spaces 9
Идентичен этой программе:
9 99 9999
9 9
переменные
Все переменные в 99 имеют имена, которые связаны одним или несколькими 9
( 9+
в регулярном выражении). Так , например, 9
, 99
и 9999999999
все различные переменные. Естественно, их бесконечно много (за исключением ограничений памяти).
Значением каждой переменной является целое число произвольной точности со знаком. По умолчанию каждой переменной присваивается собственное числовое представление. Поэтому, если он не был переназначен, значением переменной 9
является число 9, а значением переменной 99
является число 99 и так далее. Вы можете думать об этом как об обработке переменных как простых чисел, пока они не будут явно назначены.
Я буду использовать V
для ссылки на произвольное имя переменной ниже.
Каждый экземпляр V
может быть заменен 9
, 99
, 999
, 9999
и т.д.
Заявления
В 99 есть пять различных типов операторов . Каждая строка в программе 99 содержит ровно одно утверждение.
Синтаксис, описанный здесь, предполагает, что все посторонние символы были удалены, все конечные пробелы были удалены, и все последовательности из нескольких пробелов были заменены одиночными пробелами.
1. Нет операции
Пустая строка не является опцией . Это ничего не делает (кроме увеличения указателя инструкции).
2. Выход
V
Одна переменная V
в строке выводит эту переменную в стандартный вывод.
Если V
имеет нечетное число 9
'( 9
, 999
и т. Д.), То V
будет напечатано целое число, деленное на 9 (в десятичном виде).
Если V
имеет четное число 9
s ( 99
, 9999
и т. Д.) , То будет напечатан символ ASCII с кодом, V
разделенным на 9, mod 128. (Это (V / 9) % 128
значение от 0 до 127.)
Пример : программа
9
9999
будет печатать 1W
. Первая строка печатается, 1
потому что 9/9 - 1. Вторая строка печатается, W
потому что 9999/9 - 1111, а 1111 mod 128 - 87, а 87 - код символа для W
.
Обратите внимание, что разрывы строк не выводятся между токенами вывода. \n
должен быть явно напечатан для разрыва строки.
3. Ввод
V
Одна переменная V
в строке с начальным пробелом принимает входные данные из stdin и сохраняет их в этой переменной.
Если V
имеет нечетное число 9
's, то пользователь может ввести любое целое число со знаком, и V
будет установлено в 9 раз больше этого значения.
Если V
имеет четное число 9
«s», то пользователь может ввести любой символ ASCII, и для него V
будет установлено значение, в 9 раз превышающее его код символа.
Пример : данный -57
и A
как вход, эта программа
9
9
99
99
будет выводить -57A
. Внутри переменная 9
будет иметь значение -513 и 99
585.
Ваш переводчик может предположить, что входные данные всегда синтаксически действительны.
4. Назначение
Это утверждение может быть сколь угодно длинным. Это две или более переменных в строке, разделенных пробелами:
V1 V2 V3 V4 V5 ...
Это присваивает сумму всех с четными индексами минус сумма с нечетными индексами (исключая ). Назначения по значению, а не по ссылке.V1
V
V
V1
Это может быть переведено на большинство языков как .V1 = V2 - V3 + V4 - V5 + ...
Итак, если есть только две переменные, это нормальное присваивание:
V1 V2
→ V1 = V2
Если их три, то это вычитание:
V1 V2 V3
→ V1 = V2 - V3
И знак +
/ -
продолжает переключаться с каждой дополнительной переменной:
V1 V2 V3 V4
→ V1 = V2 - V3 + V4
Пример : эта программа выдаст 1110123
:
999 Prints triple-nine divided by nine (111).
999 9 9 Assigns triple-nine to zero (nine minus nine).
999 Prints triple-nine divided by nine (0)
9 999 9 Assigns single-nine to negative nine (zero minus nine).
999 999 9 Adds nine to triple-nine (really subtracts negative nine).
999 Prints triple-nine divided by nine (1).
999 999 9 Adds nine to triple-nine (really subtracts negative nine).
999 Prints triple-nine divided by nine (2).
999 999 9 Adds nine to triple-nine (really subtracts negative nine).
999 Prints triple-nine divided by nine (3).
5. Перейти (прыгать, если все ноль)
Это утверждение также может быть сколь угодно длинным. Это две или более переменных в строке, разделенных пробелами, с начальным пробелом :
V1 V2 V3 V4 V5 ...
Если некоторые из значений, кроме того , ненулевые, то это ведет себя так же, как отсутствие операции. Указатель инструкции перемещается на следующую строку как обычно.V1
Если все значения, кроме того, равны нулю, указатель инструкции перемещается на номер строки . Строки индексируются нулем, поэтому, если ноль, указатель перемещается на верхнюю строку. Программа завершается (обычно без ошибок), если она отрицательна или превышает максимально возможный индекс (количество строк минус одна).V1
V1
V1
V1
Обратите внимание, что здесь не было разделено на 9. И поскольку невозможно, чтобы переменная была значением, не кратным 9, можно перейти только к номерам строк, кратным 9.V1
Примеры:
Эта программа напечатает 1
навсегда:
9 Prints single-nine divided by nine (always 1).
99 9 9 Assigns double-nine to zero.
99 99 Jumps to line zero (top line) if double-nine is zero.
Эта программа
99999999 Print G.
999 99 Set triple-nine to ninety-nine.
9999999999 9999999999 9999999999 99 99 9 9 999 999 Set 10-nine to zero.
99999999999 9999999999 Set 11-nine to zero.
999 Print triple-nine's value divided by nine. (This is the ninth line.)
99999999 Print G.
999 999 9 Subtract nine from triple-nine.
99999 999 Jump to line 5-nines if triple-nine is zero (ends program).
9 99999999999 9999999999 Jump to line nine if 10-nine and 11-nine are zero (always jumps).
выведет числа от 11 до 1 в порядке убывания, окруженные G
символами:
G11G10G9G8G7G6G5G4G3G2G1G
дополнительные детали
Идеальный интерпретатор будет запускаться из командной строки с именем файла программы 99 в качестве аргумента. Ввод / вывод также будет выполняться на лету в командной строке.
Вы можете, однако, просто написать функцию интерпретатора, которая принимает в программу строку, а также список входных токенов (например ["-57", "A"]
). Функция должна напечатать или вернуть выходную строку.
Немного разные способы запуска интерпретатора и обработки ввода / вывода хороши, если эти опции невозможны на вашем языке.
Бонус: Напишите что-нибудь классное в 99, и я с удовольствием выложу это в качестве примера.
- Вот Pastebin из аккуратной программы "99 бутылок пива" из ответа Mac .
Надеюсь, вам понравился мой 99-й вызов! : D