Antecedentes
Stack Cats es un lenguaje esotérico reversible creado por Martin Ender. Cada comando en Stack Cats es el inverso de sí mismo (representado como un carácter simétrico, como -_:T|
), o tiene su comando inverso (representado como la imagen especular, como ()
{}
[]
<>
). Stack Cats tiene un fuerte requisito sintáctico de que todo el programa debe ser la imagen especular de sí mismo. Tenga en cuenta que esto significa que cualquier programa válido de Stack Cats es un ambigrama de imagen espejo natural .
Aquí está todo el conjunto de comandos de Stack Cats:
- Auto-simétrica:
!*+-:=ITX^_|
- Pares simétricos:
()
{}
[]
<>
\/
Cualquier otro personaje no es válido; cualquier entrada que tenga un carácter que no esté en el conjunto de caracteres anterior debería generar falso.
El lenguaje tiene una restricción adicional ()
y los {}
pares deben estar siempre equilibrados, pero en aras de la simplicidad, no tiene que verificar esta condición.
Los siguientes son algunos ejemplos de un programa válido de Stack Cats (una vez más, tenga en cuenta que no verifica los parens equilibrados):
{[+]==[+]}
[)>^<(]
({T)}|{(T})
<(*]{[:!-_:>}<[<)*(>]>{<:_-!:]}[*)>
Estos no son:
b<+>d
())(
({[<++<]})
Desafío
Escriba un programa o función que determine si la cadena dada es un programa válido de Stack Cats. Su código también debe ser un ambigrama de imagen espejo natural , lo que significa:
- Su código debe ser una imagen especular de sí mismo.
- Su código puede tener una o más líneas nuevas, siempre y cuando todo el código, mostrado de forma natural, sea una imagen reflejada de sí mismo.
- Puede omitir o agregar espacios en blanco al final de cada línea, ya que no cambia la visualización.
- Los caracteres de tabulación no están permitidos ya que tienen cierta ambigüedad en la pantalla.
Nota: su código no tiene que ser un programa válido de Stack Cats; puede contener ciertos caracteres adicionales que no están permitidos en Stack Cats. (Consulte a continuación la lista completa).
Por ejemplo, los siguientes dos programas son simétricos (y, por lo tanto, una presentación válida ), mientras que el tercero no lo es:
({bTd})
[<q|p>]
({bTd})
IXI
({bTd})
IXI
- Con respecto a la "simetría de espejo", solo se considera la simetría de estilo Stack Cats (por ejemplo,
({IH})
no es una presentación válida, aunque tenga simetría de espejo). - Su código solo puede contener estos conjuntos de caracteres, además de nueva línea:
- Auto-simétrica: espacio (
0x20
) +!"'*+-.8:=AHIMOTUVWXY^_ovwx|
- Pares simétricos:
()
/\
<>
[]
bd
pq
{}
- Auto-simétrica: espacio (
El conjunto de caracteres se elige para ser estrictamente simétrico o auto-simétrico cuando se muestra como código en SE.
Entrada y salida
El rango de entrada es cualquier cadena de una línea de caracteres ASCII imprimibles .
Puede elegir tomar la entrada como una cadena, una lista de caracteres o una lista de valores ASCII.
Puede elegir la salida:
- Cualquiera de los valores de verdad / falsedad definidos por el idioma de su elección
- Los valores de resultado reales pueden diferir entre las entradas (por ejemplo, la salida 1 para una entrada verdadera y 2 para otra verdadera).
- El intercambio de valores de verdad y falsedad no está permitido.
- Dos valores constantes para verdadero / falso respectivamente
- En este caso, los valores del resultado deben ser exactamente uno de los dos valores constantes.
Debe especificar su método de entrada y valores de salida en su envío.
Condición ganadora
Este es el código de golf , por lo que gana los bytes más bajos en cada idioma.
Notas
- Las lagunas estándar están prohibidas como de costumbre.
- Por supuesto, puede resolver esto en Stack Cats, pero la posibilidad es que no pueda usar una bandera que permita reducir el tamaño de su código a la mitad. Y es un lenguaje muy difícil de aprender: P
fuente
#
no permitido?Respuestas:
JavaScript (ES6),
487467378298292280266264 bytesGuardado 14 bytes gracias a @Bubbler
Define una función anónima que toma una matriz de caracteres y devuelve la salida deseada. El resultado es verdadero / falso; generalmente
1
/0
, pero la cadena vacía datrue
.¿Cómo?
El truco más obvio es usarlo
//\\
como punto central para comentar la versión duplicada del código. Después de eso, se convierte en un juego de averiguar la forma más corta de resolver el problema utilizando solo el juego de caracteres dado.El primer problema con el que nos encontramos es la falta de palabras clave y elementos integrados. Aún tenemos milagrosamente
.pop()
, pero todo lo demás tendrá que hacerse a través de los operadores permitidos (que incluyea[b]
yf(c)
), con recursión para emular bucles.El segundo problema es la falta de operadores lógicos. Ninguno de los dos
&
y?
se les permite, lo que significa que la única operadora de toma de decisiones que podemos utilizar es||
. Por lo tanto, tenemos que estructurar cuidadosamente nuestra lógica para dar cuenta de esto.Lo primero que hice fue definir una función
T
que refleje un carácter individual. La idea básica es recorrer cada personaje en una cadena de caracteres compatibles con espejo, probando la igualdad de cada uno con el personaje dado. Si es igual, devolvemos su espejo: el carácter aindex^1
para(){}[]<>\/
, o el propio carácter para el resto.El primer problema que encontré aquí fue obtener el char duplicado o un valor falso en cada iteración. La solución que finalmente se me ocurrió fue
(x!=A[o]||A)[o^o<88/8]
, dondex
está el carácter de entrada,A
es el alfabeto reflejado yo
es el índice actual. Six
no es lo mismo queA[o]
, esto datrue
, y la expresión de índice se evalúa comoundefined
; de lo contrario,||A
se activa y terminamos obteniendoA[o^(o<11)]
.El segundo problema es cómo terminar la recursión. Descubrí que la mejor manera de hacer esto es simplemente concatenar los resultados de cada iteración, devolviendo la cadena vacía cuando
A
se alcanza el final de . Esto nos presenta otros dos problemas: convertir laundefined
s en cadenas vacías y devolver||
algo a la cadena vacía . Estos pueden resolverse con abuso de matriz:[a]+""
proporciona la representación de cadenaa
o la cadena vacía sia
no está definida. Como[]
beneficio adicional, es verdadero pero se stringifica a la cadena vacía, por lo que podemos usar esto convenientemente como una "cadena vacía verdadera".Ahora podemos usar la
T
función para reflejar cualquier carácter individual. Hacemos esto de forma recursiva, comparando el espejo deI[v++]
queI.pop()
hasta que se alcanza el final de la serie de caracteres. No podemos usar&&
o&
verificar si todas las comparaciones son verdaderas, pero utilícelas*
en su lugar. Multiplicar todos estos resultados juntos da1
si cada personaje es el espejo del opuesto, o0
si alguna comparación falla.Y así es básicamente cómo funciona esta respuesta. Probablemente no lo expliqué muy claramente, así que por favor haga cualquier pregunta que pueda tener y señale cualquier error que haya cometido.
fuente
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 bytesStax ,
7670 bytesEjecutar y depurarlo
Stax es amigo de Stack Cats y tiene aspectos internos para generar la mitad posterior de un programa de Stack Cats de la primera mitad. Si no nos importa la restricción en la fuente y no necesitamos verificar el juego de caracteres, aquí hay una solución de 4 bytes:
4 bytes
Ejecutar y depurarlo
Explicación
fuente
R
yW
es realmente interesante. La finalización del programa porpq
combinación también es impresionante para mí.:R
y:W
. Siento que no puedo evitar decirles a todos que hay internos en Stax que hacen esto.