Eu estava navegando em esolangs e me deparei com este idioma: https://github.com/catseye/Quylthulg .
Uma coisa interessante sobre essa linguagem é que ela não usa prefixo, postfix ou infix, usa as três , chamando-a de notação "panfix".
Aqui está um exemplo. Para representar infix normais 1+2
em panfix, torna-se: +1+2+
. Observe como o operador está antes, no meio e depois dos operandos. Outro exemplo é (1+2)*3
. Isso se torna *+1+2+*3*
. Observe novamente como *
está em todos os três lugares em relação aos operandos +1+2+
e 3
.
O desafio
Como você deve ter adivinhado, sua tarefa neste desafio é converter uma expressão de infix em panfix.
Alguns esclarecimentos:
- Você só precisa lidar com as quatro operações básicas:
+-*/
- Você não terá que lidar com as versões unárias daquelas, apenas binárias
- Você tem que lidar com parênteses
- Suponha as regras de precedência normais da
*/
época+-
e associe à esquerda para todas elas. - Os números serão números inteiros não negativos
- Opcionalmente, você pode ter espaços na entrada e na saída
Casos de teste
1+2 -> +1+2+
1+2+3 -> ++1+2++3+
(1+2)*3 -> *+1+2+*3*
10/2*5 -> */10/2/*5*
(5+3)*((9+18)/4-1) -> *+5+3+*-/+9+18+/4/-1-*
Isso é código-golfe , então o código mais curto em bytes vence!
fonte
S.split``
deve ser[...S]
, embora possa realmente ajudar a combinar/\d+|./g
antecipadamente e trabalhar com isso.Mathematica,
203195 bytesProvavelmente isso é menos que eficiente, mas parece fazer o trabalho.
Esta é uma função anônima que pega uma expressão real e retorna uma string com notação panfix. O Mathematica classifica a precedência dos operadores no momento da análise, em vez do tempo da avaliação, portanto, o aninhamento deve ser automagicamente correto. Pelo menos os casos de teste funcionam como esperado.
Explicação: É fácil interpretar toda a expressão como uma árvore, assim:
Nesse estágio, os operadores (todos os nós que não são uma folha) não são mais operadores, eles foram realmente convertidos em strings como
"+"
. Os números inteiros também são convertidos em cadeias. Em seguida, uma regra de substituição repetida converte todos os nós que possuem exatamente duas folhas no panfixparent-leaf1-parent-leaf2-parent
. Após algumas iterações, a árvore reduz para uma única sequência.A principal perda na contagem de bytes é que o Mathematica interpreta
E isso acontece também no momento da análise.
Golpeou um pouco, já que o padrão
a_/b_
também é interpretado comoa_ * (b_)^(-1)
. Também algumas pequenas otimizações em outros lugares.fonte
Prolog, 87 bytes
Essa é uma função (principalmente porque a gravação de um programa completo possui níveis de pesadelo no Prolog; normalmente, mesmo se você compilar um programa, ele produz um REPL quando executado), chamado
p
. Ele recebe as entradas do stdin e as saídas no stdout. Observe que você precisa anexar um período à entrada, o que é uma conseqüência infeliz da maneira como as rotinas de entrada do Prolog funcionam (elas usam períodos na entrada da mesma maneira que outros idiomas usam novas linhas); que pode ou não desqualificar a resposta.Explicação
Operadores aritméticos, no Prolog, são normalmente interpretados como construtores de tuplas . No entanto, eles obedecem às mesmas regras de precedência que os operadores aritméticos reais nos quais eles se baseiam; você pode formar tuplas com notação infix
+
e-
vincular com menos força que*
e/
, com precedência da esquerda para a direita dentro de um grupo. É exatamente isso que a pergunta pede; portanto, podemos ler uma tupla aninhada inteira da entrada e ela já possui a estrutura correta. Isso é o quep
faz.Em seguida, precisamos convertê-lo em notação panfix.
x
converte a entrada em uma lista panfixed de construtores e inteiros, e pode ser lido como uma frase Inglês quase diretamente: "x
deT
é: seT
é uma tupla com construtorO
e argumentosA
,B
e, em seguidaO
,x
doA
,O
,x
deB
,O
, elseT
". Finalmente, precisamos apenas imprimir a lista sem separadores (ou seja, usarmaplist
para chamarwrite
cada elemento da lista).Eu usei o SWI-Prolog para testar isso, porque minha versão do GNU Prolog ainda não o
maplist
foi (aparentemente foi adicionada a uma versão mais recente), mas geralmente deve ser bastante portátil entre as implementações do Prolog.fonte