`:_64/"32}
,` (3 :=-{
"`{"; _v2$ ;`3
"`".:@ ; ".5(`3.
< "" `^`;>
Еще один сговор с @ MartinBüttner и более безумной стороной лабиринтного спектра - впервые у нас все четыре ^>v<
в одной программе. Попробуйте онлайн!
объяснение
Общий алгоритм, который работает в цикле, выглядит следующим образом:
1. Read a char
2. If EOF:
3. Move all digits from auxiliary stack to main
4. Output all digits on main stack
5. Halt
Otherwise:
6. If char is a letter (c >= 64):
7. If random turns left:
8. Output char XOR 32
Otherwise:
9. Output char
Otherwise:
10. Shift char to auxiliary stack
11. If char is space (c-32 == 0):
12. Pull char back from auxiliary stack
13. Output underscore
Otherwise:
14. Continue loop
Чтобы сохранить объяснение компактным, вот примерно то, как каждая часть программы соответствует псевдокоду выше:
Вот интересные части.
Получение случайности в Лабиринте
Есть только один способ получить случайность в Лабиринте, и это когда IP пытается идти вперед, но 1) нет ни пути вперед, ни назад, и 2) есть пути, доступные слева и справа. В этом случае IP случайным образом выбирает между левым и правым маршрутами.
Это возможно только с помощью ^>v<
операторов, которые выталкивают n
и сдвигают строку / столбец n
на 1. Например, программа ( попробуйте онлайн! )
" 1
""v!@
2
!@
выводит 1 или 2 случайным образом, так как v
смещение столбца со смещением 0 (т. е. столбца, на котором включен IP) на 1, что приводит к
"
""1!@
v
2!@
IP направлен вправо и пытается идти вперед (вершина стека равна нулю), но не может. Он также не может двигаться назад, поэтому он случайным образом выбирает между левым или правым.
Гольф трюки
Программа запускается с первого символа в порядке чтения, что, как вы заметите, на самом деле является шагом 6. Однако, выталкивание из пустого стека Лабиринта дает 0, поэтому выполняются шаги 10 и 14, смещая ноль во вспомогательный стек, что эффективно нет оп.
Основной стек фактически пуст после каждой итерации, что позволяет нам обрабатывать макет кода, используя >
и <
неявные нули внизу. >
Оборачивает нижнюю строку вокруг так , что IP перемещается от нижнего правого угла к нижнему левому, и <
сдвигает строку назад. Затем IP успешно перемещается вверх по левому столбцу, чтобы продолжить цикл.
Цифры в лабиринте лопаются n
и толкаются 10*n + <digit>
. Кроме того, символы передаются по модулю 256 перед выводом. Соединение этих двух значений позволяет нам вывести 95 (подчеркивание), выполнив `33
32 (пробел), что работает потому, что -3233 % 256 = 95
. Несмотря на то, что есть другие способы превратить 32 в 95 ( ;95
самый простой), работа с отрицательным числом позволяет нам немного сжать код левыми поворотами.