Це було напрочуд хитро, і я не переконаний, що це оптимально ...
<.@!$?
Після прокладки та розгортання коду це являє собою наступну шістнадцяткову сітку:

Для цього використовується аналогічний потік керування, як у моєї недавньої програми без кішок , що рухається по діагоналях. Для цього ми починаємо, відхиливши вказівник інструкції (IP) зліва, де фіолетова доріжка обертається до лівого нижнього кута.
?читає вхід як ціле число. !друкує його назад. .це просто неоперація. Тепер кут сітки виступає як гілка:
Якщо вхід був 0, IP буде продовжуватися по червоному шляху, який просто припиняє програму @.
Якщо вхід був 1, IP буде продовжуватися зеленим шляхом. Знову ж таки, .це просто $бездіяльність , але це еквівалент батуту Бефунге: він пропускає наступну інструкцію. Після завершення обговорення наступною інструкцією буде те ?, але завдяки $виконанню насправді продовжується синім шляхом, починаючи з !друку іншої копії 1. Цей цикл, який містить лише !..$зараз, повторюється нескінченно.
Дослідження контрольного потоку в Гексагоні ...
Я вважаю, що вищезазначене рішення є оптимальним. Я написав грубої форсер, який перевіряє всі 6-байтні програми шестикутників, які містять принаймні по одній з них ?!@(які необхідні; я також перевірив :і %замість цього @завершити з помилкою поділу на нуль, але це теж не допомогло). Чек роздруковує всі програми, які: а) виробляють 0вхід 0і завершують; б) виробляють принаймні дві 1секунди (і нічого іншого) і не припиняються протягом перших 60 тиків програми (200 тиків для 5-байтних рішень) . Я сумніваюся, що будь-яке дійсне рішення потребує більше 200 тиків, щоб правильно надрукувати перше 0чи друге 1на такій невеликій сітці, тому я не думаю, що я пропустив жодне потенційне рішення.
Пошук не дав жодних результатів для 5 байт, але 57 результатів для 6 байт (використовуючи @; немає необхідності припиняти помилку, якщо ми можемо вирішити це чисто в тій же кількості байтів). З цих 57 лише 6 були помилковими, які насправді надрукували лише два 1s, а потім увійшли до нескінченного циклу, не друкуючи більше. Одне рішення було перераховано двічі, оскільки воно містило дві !команди. Це залишає рівно 50 дійсних рішень.
Існує певна кількість виродженості між рішеннями, коли один або два символи не є істотними, наприклад, тому що вони фактично не спрацьовують. Рішення можна згрупувати в 23 набори справді відмінних програм (в деяких випадках існує лише одна різниця символів між двома наборами, але це суттєво змінює потік управління, тому я їх порахував окремо). Дві групи навіть користуються декількома вказівниками вкрай несподівано. Оскільки я б ніколи не придумав більшість цих способів використання гілок і дзеркал, вони роблять дуже цікаве вивчення можливих видів контрольного потоку в Гексагоні, і я, безумовно, навчився деяких нових хитрощів для майбутніх гольфів.
Загальний потік управління майже завжди однаково: читати номер, роздрукувати його. Якщо він 0знайде спосіб до @, якщо не продовжувати циклічно !, зберігаючи значення краю 1. Є чотири помітні винятки:
- Одне рішення (одне з двома
!) друкує два 1с за ітерацію через сітку, тому друкується приблизно вдвічі швидше, ніж більшість програм. Я це позначив x2нижче.
- Кілька рішень (ті , які містять
o) замінити 1з 111(символьним кодом o), тому вони друкують три 1 з на ітерацію, що роблять їх надрукувати приблизно в три рази швидше, ніж в більшості програм. Я це позначив x3нижче.
- Два рішення додають a
1до значення краю в кожній ітерації (так 1-> 11-> 111-> ...). Вони друкуються дуже швидко, але в кінцевому підсумку у них залишиться пам'ять. Я це позначив OoMнижче.
- Два рішення входять в дуже тугий цикл, який просто відскакує назад і вперед над
!, друкуючи на кожній іншій галочці (замість кожної 5-ї або близько того), що робить їх трохи швидшими (і акуратнішими). Я це позначив ><нижче.
Отже, тут весь зоопарк:
#1 #5 #12 #19
?!/$.@ ?$!>$@ .?!/$@ |!|?$@ # ><
?!/$1@ # OoM ?$!|$@ =?!/$@
?!/$=@ #20
?!/$\@ #6 #13 $@.?<!
?!/$o@ # x3 ?/!<|@ .?/!$@ $@1?<! # OoM
?!/$!@ # x2 =?/!$@ $@=?<!
#7 $@o?<! # x3
#2 ?\!<|@ #14
?!>$)@ \!?__@ #21
?!>$1@ #8 _>_!?@
?!>$o@ # x3 ?<!>$@ # >< #15
?!|$)@ \_?!$@ #22
?!|$1@ #9 <!@.$?
?!|$o@ # x3 ?\$!@$ #16 <!@/$?
\_?!_@ <!@=$?
#3 #10 <$@!$?
?!|)$@ ?~#!@) #17 <.@!$?
?!|1$@ ?~#!@1 $$?\@! </@!$?
?!|o$@ # x3 <=@!$?
#11 #18
#4 ?$)\@! \$?\@! #23
?_!<@> ?$1\@! <<@]!?
?$o\@! # x3
Далі - короткий посібник для кількох представницьких груп. Особливо варто переглянути групи 10 та 23. Існує багато інших цікавих, а іноді і суперечливих шляхів в інших групах, але я думаю, що я вам нудьгував досить наприкінці цього. Для всіх, хто дійсно хоче вивчити Гексагонію, це, безумовно, варто вивчити, хоча вони демонструють ще більш можливе використання дзеркал та $.
1 група
Це не набагато складніше, ніж моє оригінальне рішення, але шляхи йдуть в різні боки. Це також дозволяє отримати найбільшу кількість варіацій в одній комірці, так як найправіший режим без операції може бути замінений на 5 різних команд, які все ще роблять це дійсним без зміни структури:

2 група
Цей досить цікавий, оскільки рухається лише горизонтально. Після завернення до >IP-адреса негайно повертається назад, забираючи гілку в кут. Це не зовсім добре видно схему, але у випадку, коли 1ми переходимо перший ряд знову, але на цей раз назад. Це також означає, що ми ?знову стикаємося , що тепер повертається 0(EOF). Це зафіксовано )(з збільшенням) для збереження друку 1s. Це також має 5 варіацій, а )також може бути 1або o, а >також може бути |:

3 група
Цей виглядає майже ідентично попередньому, але безладний як пекло. До удару, |а потім переходу нижнього або верхнього ряду це те саме. Але у випадку з петлею, $тепер перескакує ) на дзеркало. Тож ми слідуємо бірюзовій стежці праворуч, тепер потрапили на приріст, пропустимо попереду, @перш ніж ми | знову завернемось, а потім повернемося до зеленої стежки вгорі.

4 група
Я думав, що цей особливо витончений:

_Дзеркало в верхньому правому куті не є з самого початку не-оп, тому ми друкуємо з !і вдарив <. 0Шлях Тепер потрапляє в горизонтальне дзеркало і завершує роботу . 1Шлях займає дуже цікаву траєкторію , хоча: вона відхиляється вниз, загортає до !, перенаправляється в сторону по горизонталі , а потім загортає назад до ! знову . Потім він продовжує рухатися в цій формі ромба, друкуючи двічі за ітерацію (кожен третій галочок).
8 група
Це одне з двох рішень із дійсно щільним циклом друку:

В <виступає в якості філії. Після обгортання двічі, 0хіти @. 1з іншого боку, спочатку пропускає ?, потім >відправляє його на $знову, так що пропускає @. Потім IP переходить у бірюзовий шлях, де він відскакує вперед-назад між >і <(обертаючись навколо краю посередині).
10 група
Одна з двох груп, яка використовує інші покажчики інструкцій, і це абсолютно красиво. У шестикутника є 6 - кожен починається з іншого кута по краю годинникової стрілки, але лише один з них активний за один раз.

Як завжди, ми читаємо з ?. Тепер ~є одинарне заперечення: воно перетворюється 1на a -1. Далі ми натискаємо на #. Це один із способів перемикання між IP-адресами: він приймає поточне значення по модулю 6 і переходить на відповідний IP (IP-адреси нумеруються 0за годинниковою стрілкою). Отже, якщо вхід був 0, то IP просто залишається тим самим і їде нудно прямо вперед !@. Але якщо вхід був 1, то поточне значення таке, -1яке є 5 (mod 6). Таким чином, ми переходимо до IP, який починається з тієї самої комірки (зелений шлях). Тепер #не працює і ?встановлює межу пам'яті 0. )з кроком, так що !друкується a 1. Тепер ми ~знову вдаримося, щоб забезпечити це#все ще не працює (на відміну від переходу на IP 1, що припинить програму). Це розумне те, наскільки добре все вписується в цю маленьку програму.
22 група
Зауважимо лише, що це група, в якій знаходиться моє оригінальне рішення. Також трапляється найбільша група, тому що неоперативний режим може знаходитися в двох різних місцях, і є кілька варіантів для фактичної (ефективної безвідмовної) команди.
23 група
Це інша група, що використовує кілька IP-адрес. Насправді для цього використовується 3 різних IP-адреси. Правий верхній кут трохи безлад, але я спробую провести вас через це:

Отже, початок, який ви бачили раніше: <відхиляє Північний-Схід, ?читає введення. Тепер ]є ще один спосіб змінити між IP-адресами: він передає контроль на наступний IP в порядку годинникової стрілки. Тож ми переключаємо управління на бірюзовий шлях, який (я знаю, що це важко побачити) починається в північно-східному куті, що йде на південний схід. Це відразу відбивається <так, що він завертається до південно-східного кута, йдучи на північний захід. Він також потрапляє, ]тому ми переходимо до наступного IP. Це сіра стежка, що починається в східному куті, йде південніше. Він друкує вхід, а потім переносить на північно-східний кут. <відхиляє шлях у горизонталь, де він відбивається іншим < . Тепер права<виконує функцію гілки: якщо вхід був 0, IP переміщується на північний схід і переходить на @. Якщо вхід був 1, IP переміщується до !, перегортається на ліворуч, <де воно відображається ... тепер у кутку він повертається назад до !, відхиляється праворуч <, відбивається ліворуч, <і шлях починається понад ...
Досить безлад, але гарний безлад. :)
Діаграми, створені за допомогою дивовижного HexagonyColorer Тімві .