Descubra se este é um programa Stack Cats válido, no estilo Stack Cats!

16

fundo

Stack Cats é uma linguagem esotérica reversível feita por Martin Ender. Cada comando no Stack Cats é o inverso de si mesmo (representado como um caractere simétrico, como -_:T|), ou possui seu comando inverso (representado como a imagem no espelho, como () {} [] <>). O Stack Cats tem um forte requisito sintático de que todo o programa seja a imagem de espelho de si mesmo. Observe que isso significa que qualquer programa Stack Cats válido é um ambigrama natural de imagem espelhada .

Aqui está todo o conjunto de comandos do Stack Cats:

  • Auto-simétrico: !*+-:=ITX^_|
  • Pares simétricos: () {} [] <> \/

Quaisquer outros caracteres são inválidos; qualquer entrada com um caractere que não esteja no conjunto de caracteres acima deve gerar false.

A língua tem restrição adicional que ()e {}pares deve ser sempre equilibrada, mas por uma questão de simplicidade, você não tem que verificar para essa condição.

A seguir estão alguns exemplos de um programa Stack Cats válido (novamente, observe que você não verifica parênteses balanceados):

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

Estes não são:

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

Desafio

Escreva um programa ou função que determine se a sequência fornecida é um programa Stack Cats válido. Seu código também deve ser um ambigrama natural de imagem espelhada , o que significa:

  • Seu código deve ser uma imagem em espelho de si mesmo.
    • Seu código pode ter uma ou mais novas linhas, desde que o código inteiro, exibido naturalmente, seja uma imagem em espelho.
    • Você pode omitir ou adicionar espaços em branco à direita em cada linha, pois isso não altera a exibição.
    • Caracteres de tabulação não são permitidos, pois têm alguma ambiguidade em exibição.

Nota: seu código não precisa ser um programa Stack Cats válido; pode conter certos caracteres extras que não são permitidos no Stack Cats. (Veja abaixo a lista completa.)

Por exemplo, os dois programas a seguir são simétricos (e, portanto, um envio válido ), enquanto o terceiro não é:

({bTd})
[<q|p>]
({bTd})
  IXI
({bTd})
IXI
  • Em relação à "simetria de espelho", apenas a simetria no estilo Stack Cats é considerada (por exemplo, ({IH})não é um envio válido, mesmo que tenha simetria de espelho).
  • Seu código pode conter apenas esses conjuntos de caracteres, além de nova linha:
    • Auto-simétrico: espaço ( 0x20) +!"'*+-.8:=AHIMOTUVWXY^_ovwx|
    • Pares simétricos: () /\ <> [] bd pq {}

O conjunto de caracteres é escolhido para ser estritamente simétrico ou auto-simétrico quando exibido como código no SE.

Entrada e saída

O intervalo de entrada é qualquer sequência de uma linha de caracteres ASCII imprimíveis .

Você pode optar por receber a entrada como uma sequência, uma lista de caracteres ou uma lista de valores ASCII.

Você pode escolher a saída:

  • Qualquer um dos valores de verdade / falsidade, conforme definido pelo idioma de sua escolha
    • Os valores reais do resultado podem diferir entre as entradas (por exemplo, saída 1 para uma entrada de verdade e 2 para outra).
    • Não é permitido trocar valores de verdade e falsidade.
  • Quaisquer dois valores constantes para verdadeiro / falso, respectivamente
    • Nesse caso, os valores do resultado devem ser exatamente um dos dois valores constantes.

Você deve especificar seu método de entrada e valores de saída no seu envio.

Condição vencedora

Isso é , portanto, os bytes mais baixos em cada idioma vencem.

Notas

  • As brechas padrão são proibidas como de costume.
  • É claro que você pode resolver isso no Stack Cats, mas a chance é que você não possa usar um sinalizador que permita reduzir o tamanho do código pela metade. E é uma linguagem seriamente difícil de entender: P
Bubbler
fonte
1
Por que afiado #não permitido?
tsh
1
@tsh É um pouco distorcido em muitas fontes, incluindo a fonte de código no SE (pelo menos é o que vejo no Chrome).
Bubbler
@DLosc Tentei esclarecer alguns pontos em torno dele. Mas se você acha que a descrição ainda não está clara, sinta-se à vontade para editar.
Bubbler

Respostas:

16

JavaScript (ES6), 487 467 378 298 292 280 266 264 bytes

Guardado 14 bytes graças a @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

Define uma função anônima que pega uma matriz de caracteres e retorna a saída desejada. A saída é verdadeira / falsa; geralmente 1/ 0, mas a string vazia fornece true.

Quão?

O truque mais óbvio é usar //\\como ponto central para comentar a versão espelhada do código. Depois disso, torna-se um jogo de descobrir a maneira mais curta de resolver o problema usando apenas o conjunto de caracteres fornecido.

O primeiro problema que encontramos é a falta de palavras-chave e de built-ins. Milagrosamente ainda temos .pop(), mas tudo o mais terá que ser feito através dos operadores permitidos (que incluem a[b]e f(c)), com recursão para emular loops.

A segunda questão é a falta de operadores lógicos. Nenhum &e ?é permitido, o que significa que o único operador de tomada de decisão que podemos usar é ||. Portanto, temos que estruturar cuidadosamente nossa lógica para explicar isso.

A primeira coisa que fiz foi definir uma função Tque espelha um personagem individual. A idéia básica é percorrer cada caractere em uma sequência de caracteres com capacidade de espelho, testando cada um quanto à igualdade com o caractere especificado. Se for igual, retornamos seu espelho - o caractere para index^1for (){}[]<>\/ou o próprio caractere para o resto.

O primeiro problema que encontrei aqui foi obter o caractere espelhado ou um valor falso em cada iteração. A solução que acabei encontrando foi (x!=A[o]||A)[o^o<88/8]: onde xestá o caractere de entrada, Ao alfabeto de espelhamento e oo índice atual. Se xnão for o mesmo que A[o], isso fornece truee a expressão de índice é avaliada como undefined; caso contrário, o ||Aé ativado e acabamos recebendo A[o^(o<11)].

O segundo problema é como encerrar a recursão. Eu descobri que a melhor maneira de fazer isso é simplesmente concatenar os resultados de cada iteração, retornando a string vazia quando o final de Aé atingido. Isso nos apresenta outros dois problemas: converter os undefinedem cadeias vazias e retornar ||alguma coisa à cadeia vazia . Estes podem ser resolvidos com abuso de array: [a]+""fornece a representação de string de aou o string vazio, se não afor definido. Como bônus, []é verdade, mas se restringe à cadeia vazia, para que possamos usá-la convenientemente como uma "cadeia vazia de verdade".

Agora podemos usar a Tfunção para espelhar qualquer caractere único. Fazemos isso de forma recursiva, comparando o espelho do I[v++]que I.pop()até o final do array de caracteres é atingido. Não podemos usar &&ou &verificar se todas as comparações são verdadeiras, mas use-as *. A multiplicação de todos esses resultados fornece 1se cada caractere é o espelho do oposto ou 0se alguma comparação falha.

E é basicamente assim que essa resposta funciona. Provavelmente não o expliquei com muita clareza; por isso, faça qualquer pergunta que possa ter e aponte os erros que cometi.

ETHproductions
fonte
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
@tsh vírgulas não são permitidos no código fonte, como eles não são simétricas (na fonte de código SE) e não tem espelho (em ASCII, de qualquer maneira)
ETHproductions
desculpe, eu perdi essa parte.
tsh
@tsh Eu também senti falta disso no início, e gastei 20 minutos em uma solução apenas para perceber que não podia ser válida: P
ETHproductions
De qualquer forma, já que você já publicou uma solução JavaScript. Nós não precisamos de uma outra solução k JSF * agora ... // Se eu fosse você, eu iria corrigir isso por apenas compilá-lo para JSF * k ...
TSH
1

Stax , 76 70 bytes

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

Execute e depure

Stax é amigo do Stack Cats e tem internos para gerar a metade posterior de um programa Stack Cats a partir do primeiro semestre. Se não nos importamos com a restrição na fonte e não precisamos verificar o conjunto de caracteres, aqui está uma solução de 4 bytes:

4 bytes

:R_=

Execute e depure

Explicação

: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
Weijun Zhou
fonte
A existência Re Wé realmente interessante. O término do programa por pqcombinação também é impressionante para mim.
Bubbler
Obrigado. As instruções são na verdade dois bytes: :Re :W. Sinto que não posso deixar de dizer a todos que há funcionários internos da Stax que fazem isso.
Weijun Zhou