Лабіринт , 28 25 24 23 22 байт
" >
?!?:|}\{@
@\?"":)!
Це була шалена забава! :) Це на сьогоднішній день найбільш густо стисла програма «Лабіринт», про яку я писав. У мене було так багато версій на 20 і 21 байт, які майже працювали, що я все ще сумніваюся, що це оптимально ...
Це приймає введення як список позитивних цілих чисел (з довільним роздільником) і друкує результат на STDOUT у вигляді цілих чисел з обмеженою лінією.
Полювання на 20/21 байт: Я перевірив усі програми форми
" XX
?!?X}\{@
@\?XX)!
де Xє будь-який розумний характер грубою силою, але не знайшли жодних дійсних рішень. Звичайно, це не означає, що коротшого рішення не існує, але неможливо змусити 20-байтні програми без гідної кількості припущень щодо його структури.
Пояснення
(Пояснення трохи застаріло, але я все ще не впевнений, що рішення оптимальне, тому я зачекаю з оновленням.)
Отже, зазвичай програми Лабіринту повинні виглядати як лабіринти. Поки покажчик інструкцій знаходиться в коридорі, він буде слідувати цьому коридору. Коли IP потрапляє в будь-який тип з'єднання, напрямок визначається виходячи з верхнього значення основного стеку Лабіринту (Лабіринт має дві стеки, з нескінченною кількістю нулів внизу). Це зазвичай означає, що будь-який нетривіальний цикл буде досить дорогим, тому що якщо у вас є не стінні комірки всюди, все є стиком, і в більшості випадків у верхній частині стека не буде потрібного значення для IP пройти шлях, який ви хотіли б пройти. Отже, ви збільшуєте петлі таким чином, щоб вони мали ціле в центрі, лише одна чітко визначена точка входу та виходу кожна.
Але цього разу мені пощастило, і все так добре поєднувалося, що я міг збити це все на одну велику грудку. :)
Контрольний потік починається на _півдні, що йде. _Штовхає нуль на основний стек. Це може здатися відключеним, але це збільшує глибину (без неявних) стеків, до 1якої нам знадобиться пізніше.
?читає ціле число з STDIN. Якщо немає більше цілих чисел, які слід читати, це натискає нуль. У цьому випадку IP продовжує рухатися на південь і одразу @припиняє програму (оскільки список вводу порожній). В іншому випадку IP перетворюється на Схід.
Зараз ми входимо в дуже щільний цикл з двома точками виходу:
!?;
\?
;
!друкує ціле число назад до STDOUT, залишаючи лише нуль на стеці. IP продовжує рухатися на Схід і ?зчитує наступне ціле число. Якщо це не нуль, ми беремо право і рухаємося на Південь. ?читає ще один (наступний рівний індекс). Знову ж таки, якщо це не нуль, ми беремо право і рухаємося на Захід.
Потім \друкується передача ліній, не змінюючи стек, тому ми беремо інше праворуч, рухаючись на північ. !друкує наступне парне ціле число. Оскільки зараз на стеці є щонайменше одне ціле (непарне) число непарного індексу, ми продовжуємо повертати праворуч і цикл повторюється.
Після того, як будь-який із них ?потрапить у кінець списку, вони натискають нуль і рухаються прямо до відповідного ;, який відкидає цей нуль.
У випадку, якщо в списку був лише один елемент, ми закінчили (тому що ми це надрукували одразу), тож IP буде продовжувати рухатися на Схід до кінця @, знову закінчуючи програму (друкуючи трейлінг на дорозі).
В іншому випадку нам також потрібно буде надрукувати цілі числа непарних індексів. У цьому випадку два контури (від двох точок виходу першого циклу) зливаються посередині ", в обох випадках повертаючи Схід.
_натискає нуль, щоб уникнути ліворуч @, і ;відкидає цей нуль. Тепер ми вводимо новий цикл:
"}
""
IP вводить це в нижній лівій комірці, рухаючись на північ, обходячи петлю за годинниковою стрілкою. }Зрушує верхню частину основного стека до допоміжної стеку. Хоча на стеку ще є елемент, IP продовжує робити все. Після того, як все переміщується в допоміжний стек (і повертається назад у процесі), IP замість цього рухається на Схід, вводячи останній цикл:
\{@
#!
\знову друкує передачу ліній, {переміщує елемент із допоміжного стеку назад до основного. Якщо це все-таки було елементом у списку, воно буде позитивним, і IP поверне на південь, де цей пункт друкується !. Потім# натискає глибину стека (і тепер _тут важливо початкове , оскільки це #забезпечує позитивну глибину стека), щоб IP все ще повертався праворуч, через \і {знову.
Після того, як ми надрукували все, {витягне нуль з нижньої частини допоміжного стеку, IP продовжується на схід і @припиняє програму.