:-:_
Wypróbuj online! W stopce zamieściłem wszystkie pozostałe 4-bajtowe rozwiązania. (Stack Cats ignoruje wszystko po pierwszym wysunięciu linii).
Spróbuj na odwrót!
Wyjaśnienie
Te -n
zakręty flag na wyjściu numerycznej (i wejścia, ale nie mają żadnych), a -m
flaga jest zazwyczaj tylko wygoda golfa, który pozwala uniknąć niepotrzebnego część kodu źródłowego. Jest tak, ponieważ każdy program Stack Cats musi mieć lustrzaną symetrię. Z -m
flagą dajesz jej tylko pierwszą połowę (plus środkową postać). Tak więc rzeczywisty program, tutaj jest:
:-:_:-:
Jak widać na pierwszym łączu TIO, jest mnóstwo 4-bajtowych rozwiązań, ale wybrałem to ze względu na jego prostotę. Stack Cats jest oparty na stosie, a ten program używa tylko początkowego stosu. Ponieważ nie mamy żadnych danych wejściowych, zawiera on pojedynczy -1
(znacznik EOF) na nieskończonej studzience zer. Trzy polecenia w programie mają następujące znaczenie:
: Swap the top two stack elements.
- Negate the top stack element (i.e. multiply by -1).
_ Pop a. Peek b. Push b-a.
Oto, w jaki sposób program modyfikuje stos (stany i polecenia są rozmieszczone naprzemiennie, aby wskazać, w jaki sposób każde polecenie zmienia stos z jednego stanu na drugi):
: - : _ : - :
-1 0 0 -1 1 0 0 1
0 -1 -1 0 0 1 1 0
0 0 0 0 0 0 0 0
… … … … … … … …
Jak się okazuje, jedynym poleceniem, które naprawdę tu robi cokolwiek, jest zmiana _
znacznika EOF w 1
. Dane wyjściowe na końcu programu są niejawne, a znacznik EOF jest opcjonalny, więc po prostu drukuje to, 1
co otrzymujemy.
Teraz, jeśli odwrócimy kod źródłowy, z powodu niejawnego dublowania, rzeczywisty program staje się:
_:-:-:_
To robi coś zupełnie innego:
_ : - : - : _
-1 1 0 0 1 -1 0 -1
0 0 1 1 0 0 -1 -1
0 0 0 0 0 0 0 0
… … … … … … … …
Tym razem dolna część stosu jest nadal, -1
więc działa jak znacznik EOF i -1
drukowana jest tylko jego górna część.
...
Teraz, gdy już to wszystko zostało powiedziane, ponieważ Stack Cats ma tak wyjątkowy związek z kodem cofania, uważam, że używanie -m
jest trochę oszustwem. Zwykle ma to na celu zaoszczędzenie bajtów poprzez pominięcie zbędnej części kodu źródłowego, ale tutaj w rzeczywistości sprawia, że wyzwanie jest o wiele łatwiejsze, a nawet pełny program krótszy. Wynika to z faktu, że odwrócenie pełnego programu zmieni program tylko, jeśli zawiera którykolwiek <>[]
, co oznacza również, że program używa wielu stosów (Stack Cats faktycznie ma taśmę stosów, gdzie wszystkie oprócz początkowej są wypełnione tylko z zerami na początek). Co więcej, odwrócenie go powoduje zamianę par <>
i []
, co nadal sprawia, że wykonanie jest symetryczne. Jedynym sposobem na przełamanie tej symetrii jest użycie tego, I
co robi -]
lub-[
lub nic w zależności od znaku górnej części stosu. Więc...
*|]I*:*I[|*
Wypróbuj online! Stopka ponownie zawiera wszystkie inne alternatywy o tej samej liczbie bajtów. Niektóre z tych wyjść 1 / -1 i niektóre 2 / -2, jak wskazano po każdym programie. Wybrałem ten, aby wyjaśnić trochę losowo jako jeden z tych, które generują 2.
Spróbuj na odwrót!
Wyjaśnienie
Jak powiedziałem, ten jest trochę dłuższy. Nawet jeśli użyjemy -m
do tego zapisu, ważyłby 6 bajtów zamiast powyższych 4.
Tym razem używane polecenia:
* 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.
Pierwszy program wykorzystuje tylko dwa stosy. To trochę niechlujne w sztuce ASCII, ale postaram się jak najlepiej. Nawiasy kwadratowe wskazują, na którym stosie znajduje się głowica taśmy, i umieszczę polecenia między każdą parą stanów stosu.
[-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
… …
Teraz -1
działa jak znacznik EOF i 2
drukuje się.
Drugi program jest taki sam, dopóki [
. Do drugiej sekundy jest praktycznie tak samo I
. Technicznie będziemy na innym stosie, ale bez wartości, wszystkie są nierozróżnialne. Ale wtedy różnica między I[
i I]
kończy się bez znaczenia:
*|[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
… … …
I tym razem nie mamy znacznika EOF, ale program nadal wyświetla -2
.
-
(0x45 = 0b00101101) działa w galaretce --
daje -1, ponieważ definiuje literał -1, podczas gdyṆ
(0xB4 = 0b10110100) daje 1, ponieważ wykonuje logiczne nie niejawnego wejścia wynoszącego zero. (OczywiścieṆ
działa równie dobrze: p)