7 , 2 байта
7 использует 3-битный набор символов, но принимает ввод, упакованный в байты (и согласно мета, языки с суббайтовыми наборами символов подсчитываются с использованием байтов для файла на диске ). Вот xxd
дамп программы:
00000000: 4cf4 L.
При передаче этого файла интерпретатору 7 он выведет следующую программу:
00000000: 4fa6 7f O..
который, в свою очередь, снова выведет исходную программу.
Так что здесь происходит? При этом не требуется чтение источника (на самом деле, я не думаю, что можно прочитать источник в 7), хотя, возможно, программа обманывает по-другому; дайте мне знать, что вы думаете. Вот как работает программа. (Обратите внимание, что у каждой из 7 команд есть два варианта, некоторые из которых не имеют имен и не могут отображаться в исходной программе. Всего имеется двенадцать команд в шести парах. Я использую жирный шрифт для активных команд, полужирный для пассивных команды, и в тех случаях, когда активная команда не имеет имени, я даю ей то же имя, что и у соответствующей пассивной команды, и полагаюсь на жирный шрифт, чтобы различать. В случае, когда оба названы, например, 7
который является активным вариантом 1
, каждая команда получает свое собственное имя, а жирный шрифт - это просто подсветка синтаксиса.)
231 7 23 Оригинальная программа, распакована в восьмеричное
231 Нажмите 237 на стек
23 толчок 23 на стек
(неявный) добавить копию вершины стека в программу
2 Дублирование вершины стека (на данный момент 23 )
3 Вывод вершины стека, всплывающий второй элемент стека
На этом этапе интерпретатор 7 видит, что вершина стека содержит команды ( 2
и 3
), которые не могут быть представлены, поэтому он выходит из вершины стека, создавая 723
(что есть). Первая команда output выбирает формат вывода; в данном случае это формат 7, «форматировать вывод так же, как и программу». Таким образом, команды упакованы в байты. Затем программа продолжается:
231 7 23 23
(неявный) добавить копию вершины стека в программу
2 Дублирующая вершина стека (в настоящее время 237 )
3 Выведите верхнюю часть стека, вставьте второй элемент стека
7 Поместите пустой элемент в стек
На данный момент в стеке нет ничего, кроме пустых элементов стека, поэтому программа завершается. Мы выводим 23
раньше. Если мы убегаем 237
(а нам нужно, потому что он содержит непредставимые команды), мы получаем 7231
. Он получает выходные данные напрямую, делая окончательный вывод программы 237231
(форматируется так же, как программа, то есть упаковывается в байты). Это 4fa67f
. (Можно отметить, что это 1
было совершенно бессмысленно с точки зрения влияния на результат; единственная причина, по которой это происходит, состоит в том, чтобы сделать две программы разными.)
Бег 237231
продолжается почти точно так же; разница в том, что бесполезные 1
запускаются сразу после первой печати (и пустой элемент неявно удаляется во второй раз, когда достигается текущий конец программы). Опять же, в 231
конечном итоге выводится сам, в 23
конечном итоге выводится сам перед ним 7
, и мы получаем 231723
исходную программу.
Наблюдатель может заметить, что две программы, несмотря на одинаковую длину в «нативном» восьмеричном языке, имеют разную длину на диске. Это потому, что 7-ми программа может быть дополнена произвольным числом в 1 бит, а упакованный формат отбрасывает конечный отступ. Вот как происходит кодирование:
2 3 1 7 2 3
010011001111010011(1...)
4 c f 4 padding
Другими словами, двух байтов 4C
F4
достаточно для представления программы, так что это все, что я использовал.