Спираль , оценка: 61921 5127 4715 4655 4191
4.X~>v+^#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v
X * X X X X X X X X X X X X X X X X X X X X X X X X X
! > h y t f V b n j u [ ( 1 3 2 ) ] U J N B F T Y H G
0;vgv*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*vvv****v+^v+^v+^v+^*v++4
X X X X X X X X X X X X X X X X X X X X X X X X X X
v v v v v v v v v v v v v v v v v v v v v v v v v v
Y y J F V u t U [ G H B n 3 N 2 j ) h g f ] ( 1 b T
Переводчик можно найти здесь .
Объяснение:
P.X~ZZ*v+^#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v
X X X X X X X X X X X X X X X X X X X X X X X X X X
! h y t f V b n j u r d c m k i e s x l o w a z p q
0;vgv*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*v*****************************************************************vP
X X X X X X X X X X X X X X X X X X X X X X X X X X
v v v v v v v v v v v v v v v v v v v v v v v v v v
z y x w V u t s r q p o n m l k j i h g f e d c b a
Программа начинается с 0
символа на четвертой строке. Первый кусок кода для запуска 0;vg
. ;
принимает число в качестве входных данных и помещает его в стек. v
помещает то, что находится в регистре (ноль) в стек. Это будет использоваться в качестве счетчика. g
является меткой, при достижении которой элемент управления переходит к другому вхождению буквы g
в коде.
Так вот где контроль теперь:
X
v
g
Поскольку во всех других направлениях есть пробелы, указатель инструкции начинает двигаться вверх.
v
помещает ноль в стек и X
немедленно выталкивает его из стека. Поскольку значение вытеснения равно нулю, указатель инструкции перемещается в X
(в противном случае он будет рассматриваться как пробел).
По умолчанию поток управления находится в режиме поворота вправо, поэтому теперь, когда он достигает перекрестка, указатель команды поворачивается вправо. v
еще раз вставляет ноль в стек, *
увеличивает регистр на единицу.
v*v*v
X
v
g
Следующее v
помещает то, что находится в регистре (номер 1) в стек, указатель инструкции пытается повернуть вправо, нажимая следующий X
. Значение, только что добавленное в стек, выталкивается и помещается в регистр. Поскольку он не равен нулю, X
он не вводится, и *
вместо этого IP переходит к следующему справа, снова увеличивая значение в регистре.
v*v*v*v*v
X X X X X
v v v v v
i h g f e
Это происходит снова и снова, пока мы не достигнем конца этой части и не *
начнется линия s. К настоящему времени значение в регистре равно 6, что является буквой g
ASCII минус буква ASCII a
. Таким образом, со строкой 97 *
с мы увеличиваем значение в регистре до 103, что соответствует букве, которую g
мы хотим напечатать. v
толкает его в стек, и P
еще один ярлык при попадании, который мы переходим к другомуP
в первой строке кода.
Здесь .
выскакивает значение из стека и печатает его как символ. После этого X
извлекает посторонний ноль из стека, затем ~
сравнивает два оставшихся значения в стеке (значения являются счетчиком и входным значением). Если значения совпадают, оператор помещает ноль в стек (иначе -1 или 1). Опять же, контроль пытается повернуть направо. X
выскакивает значение сравнения из стека, если оно равно нулю X
, и после его !
ввода завершает программу.
P.X~ZZ*v+^
X
!
В противном случае IP-адрес продолжается до Z
метки, которая в этом случае переходит только на один шаг вправо. Причиной этого является то, что при прыжке значение в регистре возвращается к нулю. *
увеличивает регистр и v
помещает полученный 1 в стек. +
извлекает два верхних элемента стека (1 и счетчик), добавляет их и помещает результат в стек (в действительности это увеличивает счетчик на единицу). ^
копирует результат из стека в регистр, не удаляя его из стека.
#
уменьшает значение в регистре на единицу, v
помещает уменьшенное значение в стек, IP-адрес пытается повернуть вправо и X
извлекает значение из стека. Если значение ненулевое, IP продолжает двигаться на восток, уменьшая значение в регистре, пока не достигнет нуля, и IP не войдет в X
ветвь.
#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v#v
X X X X X X X X X X X X X X X X X X X X X X X X X
h y t f V b n j u r d c m k i e s x l o w a z p q
Ветвь приводит к метке, соответствующей значению счетчика. После нажатия на метку элемент управления переходит к другому вхождению метки в раздел, где мы начали с метки g
, начиная еще одну итерацию. Как и в случае g
, значение в регистре увеличивается до значения ASCII буквы, которую мы должны напечатать. Затем символ печатается и счетчик увеличивается, выбирается другая метка. Это происходит до тех пор, пока после последней итерации счетчик не станет равным входу, и программа не завершится.
Редактировать:
P.X~Zv+^
X *
! Z
Достигает того же, что и
P.X~ZZ*v+^
X
!
но с меньшими пробелами.
Изменить 2:
vv****v+^v+^v+^v+^*v++P
Может использоваться вместо:
*****************************************************************vP