:-:_
Спробуйте в Інтернеті! У колонтитулі я включив усі інші 4-байтові рішення. (Стек Cats ігнорує все після першого передачі рядків.)
Спробуйте навпаки!
Пояснення
В -n
прапор черзі на цифровий вихід (і вхід, але ми не маємо який - або), і -m
прапор , як правило , тільки для зручності гри в гольф , який дозволяє уникнути надлишкової частини вихідного коду. Це тому, що кожна програма Stack Cats повинна мати дзеркальну симетрію. За допомогою -m
прапора ви надаєте йому лише першу половину (плюс центральний символ). Отже, власне програма тут:
:-:_:-:
Як ви бачите в першому посиланні TIO, є тонна 4-байтових рішень, але я вибрав це для простоти. Stack Cats базується на стеці, і ця програма використовує лише початковий стек. Оскільки ми не маємо жодного вводу, він містить один -1
(маркер EOF) поверх нескінченного колодязя нулів. Три команди в програмі мають таке значення:
: Swap the top two stack elements.
- Negate the top stack element (i.e. multiply by -1).
_ Pop a. Peek b. Push b-a.
Отже, ось як програма модифікує стек (стани і команди розміщуються в шахматному порядку, щоб вказати, як кожна команда змінює стек з одного стану в інший):
: - : _ : - :
-1 0 0 -1 1 0 0 1
0 -1 -1 0 0 1 1 0
0 0 0 0 0 0 0 0
… … … … … … … …
Як виявляється, єдина команда, яка насправді робить що-небудь тут, - _
це перетворює наш маркер EOF в a 1
. Вихід у кінці програми неявний, і маркер EOF необов’язковий, тому це просто роздруковує отримане 1
нами.
Тепер, якщо ми повернемо вихідний код, через неявне дзеркальне відображення, фактична програма стає:
_:-:-:_
Це робить щось зовсім інше:
_ : - : - : _
-1 1 0 0 1 -1 0 -1
0 0 1 1 0 0 -1 -1
0 0 0 0 0 0 0 0
… … … … … … … …
Цього разу нижня частина стека - це все-таки -1
так, що вона діє як маркер EOF і -1
друкується лише верхня частина.
...
Тепер, маючи на увазі все, оскільки у Stack Cats є така унікальна взаємозв'язок із кодом, що повертається назад, я відчуваю, що використання -m
- це трохи обман. Зазвичай це призначено лише для збереження байтів, опускаючи зайву частину вихідного коду, але тут це фактично робить виклик набагато простішим і навіть повну програму коротшою. Це тому, що повернення повної програми змінить програму лише у тому випадку, якщо вона містить якусь <>[]
, що також означає, що програма в кінцевому рахунку використовує кілька стеків (у Stack Cats насправді є стрічка стеків, де всі, крім початкової, заповнені лише з нулями для початку). Крім того, реверсування його потім просто змінює місцями <>
і []
парами, що все ще робить виконання симетричним. Єдиний спосіб порушити цю симетрію - це використовуватиI
що робить-]
або-[
або нічого, залежно від знака верхньої частини стека. Так...
*|]I*:*I[|*
Спробуйте в Інтернеті! Нижній колонтитул знову включає всі інші альтернативи при тому ж рахунку байтів. Деякі з них виводять 1 / -1, а деякі виводять 2 / -2, як зазначено після кожної програми. Я вибрав це, щоб щось пояснити випадковим чином, як одне з тих, що виводять 2.
Спробуйте навпаки!
Пояснення
Як я вже говорив, ця трохи довша. Навіть якби ми використали -m
для цього позначення, воно буде важити в 6 байт замість вище 4.
Команди, які використовуються цього разу:
* Toggle the least significant bit of the top of the stack.
| Reverse the longest non-zero of prefix on this stack.
[] Move one stack to the left/right and take the top of the current stack with you.
I If the top of the stack is positive, -], if it's negative, -[, otherwise do nothing.
: Swap the top two stack elements.
Перша програма використовує лише два стеки. Це трохи безладно робити в мистецтві ASCII, але я постараюся зробити все можливе. Квадратні дужки вказують, на якій стеці розміщена головка стрічки, і я поставлю команди між кожною парою станів стека.
[-1]
… 0 0 …
0 0
… …
*
[-2]
… 0 0 …
0 0
… …
| (does nothing)
]
[-2]
… 0 0 …
0 0
… …
I
[2]
… 0 0 …
0 0
… …
*
[3]
… 0 0 …
0 0
… …
:
[0]
… 3 0 …
0 0
… …
*
[1]
… 3 0 …
0 0
… …
I
[-1]
… 3 0 …
0 0
… …
[
[-1]
… 3 0 …
0 0
… …
|
[ 3]
… -1 0 …
0 0
… …
*
[ 2]
… -1 0 …
0 0
… …
Тепер він -1
виступає як маркер EOF і2
друкується.
Інша програма залишається тією самою, що й до [
. Це все одно практично все так само до другого I
. Ми технічно знаходимося на іншому стеку, але без значень на них, всі вони не відрізняються. Але тоді різниця між I[
і I]
закінчується важливою:
*|[I*:*I
[-1]
… 3 0 0 …
0 0 0
… … …
]
[-1]
… 3 0 0 …
0 0 0
… … …
| (does nothing)
*
[-2]
… 3 0 0 …
0 0 0
… … …
На цей раз у нас немає маркера EOF, але програма все одно виводить -2
.
-
(0x45 = 0b00101101) працює в Jelly - отримує-
-1, оскільки він визначає буквальний -1, аṆ
(0xB4 = 0b10110100) дає 1, оскільки він виконує логічну не неявного введення нуля. (Звичайно,Ṇ
працює так само добре: p)