# Background

Stack Cats is a reversible esoteric language made by Martin Ender. Each command in Stack Cats is either the inverse of itself (represented as a symmetric character, such as -_:T|), or has its inverse command (represented as the mirror image, such as () {} [] <>). Stack Cats has a strong syntactic requirement that the whole program should be the mirror image of itself. Note that this means any valid Stack Cats program is a natural mirror-image ambigram.

Here is the whole command set of Stack Cats:

• Self-symmetric: !*+-:=ITX^_|
• Symmetric pairs: () {} [] <> \/

Any other characters are invalid; any input having a character not in the character set above should output false.

The language has additional constraint that () and {} pairs must be always balanced, but for the sake of simplicity, you don't have to check for this condition.

The following are some examples of a valid Stack Cats program (again, note that you don't check for balanced parens):

{[+]==[+]}
[)>^<(]
({T)}|{(T})
<(*]{[:!-_:>}<[<)*(>]>{<:_-!:]}[*)>


These are not:

b<+>d
())(
({[<++<]})


# Challenge

Write a program or function that determines if the given string is a valid Stack Cats program. Your code should also be a natural mirror-image ambigram, which means:

• Your code should be a mirror image of itself.
• Your code may have one or more newlines, as long as the whole code, displayed naturally, is a mirror image of itself.
• You can omit or add trailing whitespaces on each line, since it doesn't change the display.
• Tab characters are not allowed since they have some ambiguity on display.

Note: your code does not have to be a valid Stack Cats program; it may contain certain extra characters that are not allowed in Stack Cats. (See below for the complete list.)

For example, the following two programs are symmetric (and thus a valid submission), while the third is not:

({bTd})
[<q|p>]
({bTd})
IXI
({bTd})
IXI
• Regarding "mirror symmetry", only Stack Cats-style symmetry is considered (e.g. ({IH}) is not a valid submission, even though it has mirror symmetry).
• Your code can only contain these sets of characters, plus newline:
• Self-symmetric: space (0x20) + !"'*+-.8:=AHIMOTUVWXY^_ovwx|
• Symmetric pairs: () /\ <> [] bd pq {}

The character set is chosen to be strictly symmetric or self-symmetric when displayed as code on SE.

# Input and Output

The input range is any one-line string of printable ASCII characters.

You can choose to take input as a string, a list of chars, or a list of ASCII values.

You can choose to output either:

• Any of the truthy/falsy values as defined by the language of your choice
• The actual result values may differ between inputs (e.g. output 1 for a truthy input and 2 for another truthy one).
• Swapping truthy and falsy values is not allowed.
• Any two constant values for true/false respectively
• In this case, the result values should exactly be one of the two constant values.

You should specify your input method and output values in your submission.

# Winning Condition

This is , so lowest bytes in each language wins.

# Notes

• Standard loopholes are forbidden as usual.
• Of course you can solve this in Stack Cats, but the chance is that you can't use a flag that allows to reduce your code size by half. And it's seriously hard language to pick up :P
• Why sharp # disallowed? – tsh Mar 26 '18 at 3:05
• @tsh It's slightly skewed in many fonts, including the code font on SE (at least it's what I see on Chrome). – Bubbler Mar 26 '18 at 3:19
• @DLosc I tried to clarify some points around it. But if you think the description is still unclear, please feel free to edit. – Bubbler Mar 26 '18 at 3:32
• – Martin Ender Mar 26 '18 at 8:34

## JavaScript (ES6), 487467378298292280266 264 bytes

Saved 14 bytes thanks to @Bubbler

I=>(V=v=>!I[v]||((T=o=>[[]][+!!A[o]]||[(I[v]!=A[o]||A)[o^o<88/8]]+T(++o))(8-8)==I.pop())*V(++v))(V|(A='(){}[]<>\\/ !*+-:=ITX^_|'))//\\(('|_^XTI=:-+*! \//<>[]{}()'=A)|V)((v++)V*(()qoq.I==(8-8)((o++)T+[[8\88>o^o](A||[o]A=![v]I)]||[[o]A!!+][[]]<=o=T))||[v]I!<=v=V)<=I


Defines an anonymous function that takes an array of chars and returns the desired output. Output is truthy/falsy; usually 1/0, but the empty string gives true.

## How?

The most obvious trick is to use //\\ as a center point to comment out the mirrored version of the code. After that, it becomes a game of figuring out the shortest way to solve the problem using only the charset given.

The first issue we run into is the lack of keywords and built-ins. We miraculously still have .pop(), but everything else will have to be done via the allowed operators (which includes a[b] and f(c)), with recursion to emulate loops.

The second issue is the lack of logical operators. Neither & and ? are allowed, which means the only decision-making operator we can use is ||. Therefore, we have to carefully structure our logic to account for this.

The first thing I did was to define a function T that mirrors an individual character. The basic idea is to loop through each character in a string of mirror-able chars, testing each for equality with the given char. If it is equal, we return its mirror—the char at index^1 for (){}[]<>\/, or the char itself for the rest.

The first problem I ran into here was getting either the mirrored char or a falsy value on each iteration. The solution I eventually came up with was (x!=A[o]||A)[o^o<88/8], where x is the input character, A is the mirroring alphabet, and o is the current index. If x is not the same as A[o], this gives true, and the index expression evaluates to undefined; otherwise, the ||A is activated, and we end up getting A[o^(o<11)].

The second problem is how to terminate the recursion. I found that the best way to do this is to simply concatenate the results of every iteration, returning the empty string when the end of A is reached. This presents us with two further problems: converting the undefineds to empty strings, and returning the empty string || something. These can be solved with array abuse: [a]+"" gives the string representation of a, or the empty string if a is undefined. As a bonus, [] is truthy but stringifies to the empty string, so we can conveniently use this as a "truthy empty string".

Now we can use the T function to mirror any single character. We do this recursively, comparing the mirror of I[v++] to I.pop() until the end of the array of chars is reached. We can't use && or & to check if all of the comparisons are truthy, but so use * instead. Multiplying all of these results together gives 1 if every character is the mirror of the one opposite, or 0 if any comparison fails.

And that is basically how this answer works. I probably didn't explain it very clearly, so please ask any questions you may have and point out any mistakes I have made.

• U=([A,...H])=>!(V=H.pop())||!(W=([x,...X]=(T="!*+-:=ITX^_|")+"(){}[]<>\\/",[o,...O]=T+")(}{][></\\")=>!x||((o!=A)+(x!=V))*(W(X,O)))()*U(H)//... 280 bytes – tsh Mar 26 '18 at 2:22
• @tsh commas are not allowed in the source code, as they are not symmetrical (in the SE code font) and have no mirror (in ASCII, anyway) – ETHproductions Mar 26 '18 at 2:28
• sorry, i missed that part. – tsh Mar 26 '18 at 2:41
• @tsh I missed it too at first, and spent 20 minutes on a solution only to realize it couldn't be valid :P – ETHproductions Mar 26 '18 at 2:42
• Anyway, since you had already posted a JavaScript solution. We do not need another JSF*k solution now... // If I were you, I would fix this by just compile it to JSF*k... – tsh Mar 26 '18 at 3:00

# Stax, 76 70 bytes

:Wx^^MH_=_"{([</!*+-:=ITX^_|":W-!*pq*!-W:"|_^XTI=:-+*!\>])}"_=_HM^^xW:


Run and debug it

Stax is friend of Stack Cats and has internals to generate the later half of a Stack Cats program from the first half. If we don't care about the restriction on the source and don't need to check the charset, here is a 4-byte solution:

## 4 bytes

:R_=


Run and debug it

## Explanation

:Wx^^MH_=_"{([</!*+-:=ITX^_|":W-!*pq...
:W                                         "Mirror" the string
Equivalent to appending the reverse of the string to itself
And map {([</\>])} to its mirror in the appended string
x^^                                      2, but we can't just use 2 here ...
MH                                    Partition the "mirror"ed string to two parts, take the later part.
_=                                  The string is the same as the original one (*)
:Wx^^MH_= is just :R_=, but we can't use R here ...
_                                 Input string
"{([</!*+-:=ITX^_|":W-           Remove valid characters from input
!          The final string is empty (**)
*         (*) and (**)
p        Pop and print result
q       Peek stack and print
Since the stack is now empty, this causes the program to terminate
...    Not executed

• The existence of R and W is really interesting. Program termination by pq combination is also impressive to me. – Bubbler Mar 28 '18 at 7:22
• Thank you. The instructions are actually two bytes: :R and :W. I feel that I can't help telling everyone there are internals in Stax that do this. – Weijun Zhou Mar 28 '18 at 8:03