:-:_
Try it online! In the footer I've included all other 4-byte solutions. (Stack Cats ignores everything after the first linefeed.)
Try the reverse!
Explanation
The -n flag turns on numeric output (and input, but we don't have any), and the -m flag is normally just a golfing convenience which lets you avoid the redundant part of the source code. This is because every Stack Cats program needs to have mirror symmetry. With the -m flag you only give it the first half (plus the central character). So the actual program here is:
:-:_:-:
As you can see in the first TIO link, there's a ton of 4-byte solutions, but I picked this one for its simplicity. Stack Cats is stack-based, and this program only uses the initial stack. Since we don't have any input, it contains a single -1 (an EOF marker) on top of an infinite well of zeros. The three commands in the program have the following meaning:
: Swap the top two stack elements.
- Negate the top stack element (i.e. multiply by -1).
_ Pop a. Peek b. Push b-a.
So here is how the program modifies the stack (states and commands are staggered to indicate how each command changes the stack from one state to the next):
: - : _ : - :
-1 0 0 -1 1 0 0 1
0 -1 -1 0 0 1 1 0
0 0 0 0 0 0 0 0
… … … … … … … …
As it turns out, the only command that really does anything here is _ which turns our EOF marker into a 1. Output at the end of the program is implicit, and the EOF marker is optional, so this just prints out the 1 we get.
Now if we reverse the source code, due to the implicit mirroring, the actual program becomes:
_:-:-:_
This does something very different:
_ : - : - : _
-1 1 0 0 1 -1 0 -1
0 0 1 1 0 0 -1 -1
0 0 0 0 0 0 0 0
… … … … … … … …
This time the bottom of the stack is still a -1 so it does act as the EOF marker and only the -1 on top of it gets printed.
...
Now with all of that said, since Stack Cats has such a unique relationship with reversing code, I feel that using -m is a little cheating. It's normally only meant to save bytes by omitting the redundant part of the source code, but here it actually makes the challenge a lot easier and even the full program shorter. This is because reversing a full program will only change the program if it contains any of <>[], which also means that the program ends up making use of multiple stacks (Stack Cats actually has a tape of stacks, where all but the initial one are only filled with zeros to begin with). Furthermore, reversing it then just swaps the <> and [] pairs, which still makes the execution symmetric. The only way to break that symmetry is to use I which does -] or -[o niente a seconda del segno della parte superiore della pila. Così...
*|]I*:*I[|*
Provalo online! Il piè di pagina include di nuovo tutte le altre alternative con lo stesso numero di byte. Alcuni di questi producono 1 / -1 e altri 2 / -2 come indicato dopo ciascun programma. Ho scelto questo per spiegarlo in modo casuale come uno di quelli che hanno prodotto 2.
Prova il contrario!
Spiegazione
Come ho già detto, questo è un po 'più lungo. Anche se abbiamo usato il-m notation for this, it would weigh in at 6 bytes instead of the above 4.
I comandi in uso questa volta:
* 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.
Il primo programma utilizza solo due pile. È un po 'complicato da fare nell'arte ASCII, ma farò del mio meglio. Le parentesi quadre indicano su quale pila si trova la testina e inserirò i comandi tra ciascuna coppia di stati di pila.
[-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
… …
Ora -1agisce come un marker EOF e il2 viene stampato.
L'altro programma è lo stesso fino a quando [. È ancora praticamente lo stesso fino al secondo I. Saremo tecnicamente su uno stack diverso, ma senza valori su di essi, sono tutti indistinguibili. Ma poi la differenza tra I[e I]finisce per essere importante:
*|[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
… … …
E questa volta, non abbiamo un marker EOF, ma il programma continua a produrre -2.
-(0x45 = 0b00101101) funziona in Jelly --produce -1 poiché definisce il letterale -1, mentreṆ(0xB4 = 0b10110100) produce 1 poiché esegue un logico non dell'input implicito di zero. (NaturalmenteṆfunziona altrettanto bene: p)