Популярный веб-комикс Homestuck использует язык программирования, предназначенный ~ATH
для уничтожения вселенных. В то время как задача кода в гольф не состоит в том, чтобы написать программу, которая уничтожит наше существование, мы будем уничтожать некоторые более ручные (хотя и менее интересные) объекты: переменные .
~ATH
(произносится как «до смерти», обратите внимание, как ~ath
работает «тильда спорт»), создавая переменную с именем THIS
, выполняя команду с помощью EXECUTE
и заканчивая программу с помощью THIS.DIE()
. Вики-страницу для использования языка в Homestuck можно найти здесь . Целью этой задачи будет создание ~ATH
переводчика.
Ради задачи я собираюсь создать некоторые детали ~ATH
, которых на самом деле не существует, но сделаю это (несколько) полезным.
- Язык будет работать только с целыми числами, которые объявлены с
import <variable name>;
. Переменная будет автоматически установлена на значение 0. Одновременно может быть импортирована только одна переменная. - Переменную
x
можно скопировать записьюbifurcate x[y,z];
, которая удалит переменнуюx
и заменит ее идентичными переменнымиy
иz
. Обратите внимание, что он не может создать переменную с тем же именем, что и удаленная. По сути, переменная переименовывается, а затем создается копия переменной с другим именем. Это кажется глупой чертой, но глупость очень глубоко укоренилась в Homestuck. - Синтаксис для написания программы, выполняющей код,
x
-~ATH(x){EXECUTE(<code>)}
. Если вы хотите , чтобы выполнить код от двух переменных одновременно, код становится вложенным, как это:~ATH(x){~ATH(y){EXECUTE(<code>)}}
. Все команды<code>
будут выполнены как на, такx
и наy
. - Теперь давайте перейдем к командам.
+
увеличивает соответствующую переменную (переменные) на 1 и-
уменьшает их на 1. И ... вот и все. - Последняя особенность в
~ATH
том, что он убивает все, с чем работает. Переменные печатаются в формате<name>=<value>
(за которым следует новая строка) в команде[<name>].DIE();
. После этого программа печатает словоDIE <name>
и символ новой строки количество раз, равное абсолютному значению значения переменной. Когда переменные уничтожаются одновременно с[<name1>,<name2>].DIE();
(вы можете уничтожить столько переменных, сколько хотите, до тех пор, пока они существуют),DIE()
команда выполняется для переменных последовательно.
Примеры программ
Программа 1:
import sollux; //calls variable "sollux"
import eridan; //calls variable "eridan"
~ATH(sollux){EXECUTE(--)} //sets the value of "sollux" to -2
~ATH(eridan){EXECUTE(+++++)} //sets the value of "eridan" to 5
[sollux].DIE(); //kills "sollux", prints "DIE sollux" twice
~ATH(eridan){EXECUTE(+)} //sets the value of "eridan" to 6
[eridan].DIE(); //kills "eridan", prints "DIE eridan" 6 times
Выход:
sollux=-2
DIE sollux
DIE sollux
eridan=6
DIE eridan
DIE eridan
DIE eridan
DIE eridan
DIE eridan
DIE eridan
Программа 2:
import THIS; //calls variable "THIS"
~ATH(THIS){EXECUTE(++++)} //sets the value of "THIS" to 4
bifurcate THIS[THIS1,THIS2]; //deletes "THIS", creates variables "THIS1" and "THIS2" both equal to 4
~ATH(THIS1){EXECUTE(++)} //sets the value of "THIS1" to 6
[THIS1,THIS2].DIE(); //kills "THIS1" and "THIS2", prints "DIE THIS1" 6 times then "DIE THIS2" 4 times
import THAT; //calls variable "THAT"
bifurcate THAT[THESE,THOSE]; //deletes "THAT", creates variables "THESE" and "THOSE"
~ATH(THESE){~ATH(THOSE){EXECUTE(+++)}EXECUTE(++)} //sets the value of "THESE" and "THOSE" to 3, then sets the value of "THESE" to 5
[THESE,THOSE].DIE(); //kills "THESE" and "THOSE", prints "DIE THESE" 5 times then "DIE THOSE" 3 times
Выход:
THIS1=6
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
THIS2=4
DIE THIS2
DIE THIS2
DIE THIS2
DIE THIS2
THESE=5
DIE THESE
DIE THESE
DIE THESE
DIE THESE
DIE THESE
THOSE=3
DIE THOSE
DIE THOSE
DIE THOSE
Это код гольф, поэтому применяются стандартные правила. Самый короткий код в байтах побеждает.
источник
~ATH
использует точку с запятой в качестве линейных окончаний дляimport
,bifurcate
иDIE
команд. И REPL и файлы в порядке. Чувствительность к регистру требуется как на входе, так и на выходе (я стараюсь~ATH
максимально соответствовать фактическому ).Ответы:
Python 2.7.6,
1244130812651253107310721071106510641063 байтаХорошо, я не беру здесь никаких записей, но речь идет о самом маленьком Python, поскольку он считывает входные данные сразу из файла, а не последовательно с течением времени. Я постараюсь сделать это позже на другом языке (и интерпретаторе, а не просто парсере). До тех пор наслаждайтесь отвратительно отвратительным чудовищем.
Примечание : открывает файл с именем
t
в рабочем каталоге. Чтобы открыть аргумент командной строки, добавьтеimport sys
в начало файла и измените't'
наsys.argv[1]
источник
Python 2,
447475463443 байтаОказывается, архивирование и шифрование программы base64 все еще экономит байты по сравнению с обычной версией. Для сравнения вот нормальный:
В основном желаемое решение "regexy wands of magic". Читает во всей программе из stdin как одну строку, заменяет выражения ~ ATH выражениями Python, которые выполняют описанную семантику, и выполняет exec () полученную строку.
Чтобы увидеть, что он делает, посмотрите на программу на python, в которую переведена вторая предоставленная тестовая программа:
Это хорошо, что
00 == 0
: PОчевидно, что несколько байт можно было бы сэкономить, используя двусмысленность в правилах. Например, не сказано, что должно произойти, если кто-то попытается
DIE()
использовать переменную, которая не былаimport
отредактирована или уже былаbifurcate
d. Мое предположение, основанное на описании, заключалось в том, что должна быть ошибка. Если ошибка не требуется, я мог бы удалитьdel
утверждение.РЕДАКТИРОВАТЬ: Исправлена ошибка, которую не тестировали тестовые примеры. А именно, как это было, каждый
~ATH
блок сбрасывал переменную в ноль, прежде чем увеличивать ее. Это стоило мне 28 байт, чтобы это исправить. Если кто-нибудь увидит лучший способ заменить~ATH
блоки, я бы хотел узнать это.РЕДАКТИРОВАТЬ 2: Сохраните 12 байтов, развернув цикл регулярных выражений, превратив их в субныри и позволив сжатию позаботиться о повторении.
РЕДАКТИРОВАТЬ 3: Сохранено еще 20 байтов путем замены внутреннего
for
цикла умножением строки.источник
import sys,re
вместоimport sys;import re
python ~ath.py < program.~ath