_8
,%
;
"}{{+_5
"= %_!
= """{
;"{" )!
Закінчується помилкою поділу на нуль (повідомлення про помилку на STDERR).
Спробуйте в Інтернеті!
Макет відчуває себе справді неефективним, але я просто не бачу способу розіграти його.
Пояснення
Це рішення засноване на арифметичному трюку Денніса: візьміть усі коди символів за модулем 8
, додайте пару з обох кінців і переконайтесь, що воно розділене на5
.
Лабіринтний праймер:
- Лабіринт має два стеки цілих чисел з довільною точністю, основний і допоміжний (iliary), які спочатку заповнені (неявне) нескінченну кількість нулів.
- Вихідний код нагадує лабіринт, де вказівник інструкції (IP) слідує за коридорами, коли може (навіть за кутами). Код починається з першого дійсного символу в порядку читання, тобто у верхньому лівому куті в цьому випадку. Коли IP доходить до будь-якої форми з'єднання (тобто декількох суміжних комірок на додаток до тієї, з якої він увійшов), він вибере напрямок на основі верхньої частини основного стеку. Основні правила: поверніть ліворуч при негативі, продовжуйте рухатись вперед, коли нуль, поверніть праворуч, коли позитивно. І коли одне з них неможливо, тому що є стіна, то IP буде приймати протилежний бік. ІС також обертається, коли потрапляє в тупики.
- Цифри обробляються шляхом множення верхньої частини основного стека на 10, а потім додавання цифри.
Код починається з невеликого циклу 2x2 за годинниковою стрілкою, який читає весь вхідний модуль 8:
_ Push a 0.
8 Turn into 8.
% Modulo. The last three commands do nothing on the first iteration
and will take the last character code modulo 8 on further iterations.
, Read a character from STDIN or -1 at EOF. At EOF we will leave loop.
Тепер ;
відкидає -1
. Вводимо ще одну петлю за годинниковою стрілкою, яка переміщує верхню частину основного стека (тобто останній символ) донизу:
" No-op, does nothing.
} Move top of the stack over to aux. If it was at the bottom of the stack
this will expose a zero underneath and we leave the loop.
= Swap top of main with top of aux. The effect of the last two commands
together is to move the second-to-top stack element from main to aux.
" No-op.
Тепер є короткий лінійний біт:
{{ Pull two characters from aux to main, i.e. the first and last (remaining)
characters of the input (mod 8).
+ Add them.
_5 Push 5.
% Modulo.
Зараз IP знаходиться на стику, який виступає гілкою для перевірки на подільність на 5. Якщо результат модуля не дорівнює нулю, ми знаємо, що вхід не є паліндром Ватсона-Крика, і ми повертаємо на схід:
_ Push 0.
! Print it. The IP hits a dead end and turns around.
_ Push 0.
% Try to take modulo, but division by zero fails and the program terminates.
В іншому випадку нам потрібно продовжувати перевіряти решту вхідних даних, щоб IP продовжував іти на південь. У {
тягне за нижню частину залишився входу. Якщо ми вичерпали вхід, то це буде 0
(знизу aux ), і IP продовжує рухатися на південь:
) Increment 0 to 1.
! Print it. The IP hits a dead end and turns around.
) Increment 0 to 1.
{ Pull a zero over from aux, IP keeps moving north.
% Try to take modulo, but division by zero fails and the program terminates.
В іншому випадку в рядку буде перевірено більше символів. ІР повертає на захід і переходить у наступний (за годинниковою стрілкою) 2х2 цикл, який складається здебільшого відсутності:
" No-op.
" No-op.
{ Pull one value over from aux. If it's the bottom of aux, this will be
zero and the IP will leave the loop eastward.
" No-op.
Після цього циклу ми знову отримали вхід на основний стек, за винятком першого та останнього символу та з нулем зверху. У ;
відкидає , 0
а потім =
міняє місцями вершини стеків, але це просто скасував перше =
в циклі, тому що ми вступаємо в цикл в іншому місці. Промийте і повторіть.