Na notação de prefixo, o operador vem antes dos argumentos, então você pode imaginar que o operador chama next()
que é chamado recursivamente. Na notação infix, o operador fica entre os argumentos, para que você possa imaginá-lo simplesmente como uma árvore de análise. Na notação postfix, o operador vem após os argumentos, para que você possa imaginá-lo como baseado em pilha.
Em qualquer notação de correção, o operador pode ir a qualquer lugar * . Se um operador aparecer e não houver argumentos suficientes, o operador aguardará até que haja argumentos suficientes. Para esse desafio, você deve implementar um avaliador anyfix muito básico. (Observe que anyfix é uma linguagem recreativa que eu abandonei e que você pode brincar aqui ou conferir aqui )
Você precisará suportar os seguintes comandos:
(Aridade 1)
- duplicado
- negativo
(Aridade 2)
- Adição
- multiplicação
- igualdade: retorna
0
ou1
.
Você pode optar por usar quaisquer cinco símbolos que não sejam espaços em branco para esses comandos. Para fins demonstrativos, usarei "
como duplicado, ×
como multiplicação e +
como adição.
Para literais, você precisa apenas suportar números inteiros não negativos, mas seu intérprete deve poder conter todos os números inteiros (dentro do intervalo de números inteiros (razoáveis) do seu idioma).
Vamos dar uma olhada em um exemplo: 10+5
. O armazenamento deve se comportar como uma pilha, não como uma fila. Então, primeiro, a pilha começa em []
e a lista de operadores em fila começa em []
. Em seguida, 10
é avaliado o literal que compõe a pilha [10]
. Em seguida, o operador +
é avaliado, o que requer dois argumentos. No entanto, há apenas um argumento na pilha, portanto, a lista de operadores na fila se torna ['+']
. Em seguida, 5
é avaliado o literal que compõe a pilha [10, 5]
. Nesse ponto, o operador '+'
pode ser avaliado como está, criando a pilha [15]
e a fila []
.
O resultado final deve ser [15]
de + 10 5
, 10 + 5
e 10 5 +
.
Vamos dar uma olhada em um exemplo mais difícil: 10+"
. A pilha e a fila começam como []
e []
. 10
é avaliado primeiro, o que faz a pilha [10]
. Em seguida, +
é avaliado, o que não altera a pilha (porque não há argumentos suficientes) e faz a fila ['+']
. Então, "
é avaliado. Isso pode ser executado imediatamente, criando a pilha [10, 10]
. +
agora pode ser avaliado para que a pilha se torne [20]
e a fila []
. O resultado final é [20]
.
E a ordem das operações?
Vamos dar uma olhada ×+"10 10
. A pilha e a fila iniciam como []
:
×
: A pilha permanece inalterada e a fila se torna['×']
.+
: A pilha permanece inalterada e a fila se torna['×', '+']
."
: A pilha permanece inalterada e a fila se torna['×', '+', '"']
.10
: A pilha se torna[10]
. Mesmo que×
deva ser o primeiro operador a ser avaliado desde que aparece primeiro,"
pode ser executado imediatamente e nenhum dos operadores antes, por isso é avaliado. A pilha se torna[10, 10]
e a fila['×', '+']
.×
agora pode ser avaliada, o que faz com que a pilha[100]
e a fila['+']
.10
: A pilha se torna[100, 10]
, o que permite+
ser avaliado. A pilha se torna[110]
e a fila[]
.
O resultado final é [110]
.
Os comandos usados nessas demonstrações são consistentes com os da linguagem anyfix; no entanto, o último exemplo não funcionará devido a um erro no meu intérprete. (Isenção de responsabilidade: seus envios não serão usados no intérprete anyfix)
Desafio
Selecione um conjunto de 5 caracteres que não sejam espaços em branco e que não digam dígitos e crie um interpretador anyfix de acordo com as especificações acima. Seu programa pode gerar a matriz singular ou o valor contido nela; é garantido que a pilha de valores contenha apenas um único valor no final da execução e que a fila de operadores fique vazia no final da execução.
Isso é código-golfe, portanto o código mais curto em bytes vence.
Casos de teste
Para esses casos de teste, duplicado é "
, negativo é -
, adição é +
, multiplicação é ×
e igualdade é =
.
Input -> Output
1+2×3 -> 9
1"+"+ -> 4
2"××" -> 16
3"×+" -> 18
3"+×" -> 36
123"= -> 1 ("= always gives 1)
1+2=3 -> 1
1"=2+ -> 3
1-2-+ -> -3
-1-2+ -> 3 (hehe, the `-1` becomes `+1` at the `-` rather than making the `2` a `-1`)
+×"10 10 -> 200 (after the 10 is duplicated (duplication is delayed), 10 + 10 is performed and then 20 * 10, giving 200)
Regras
- As brechas padrão se aplicam
- Você pode pegar o intérprete oficial anyfix e jogar golfe, se desejar. Espere perder terrivelmente.
A entrada será dada como uma sequência e a saída como uma matriz, um único número inteiro, fora da representação da sequência. Você pode assumir que a entrada conterá apenas espaços, dígitos e os 5 caracteres que você escolher.
* na verdade não
fonte
0
e1
?×+"10 10
nos casos de teste ou em qualquer outro exemplo que seja 1) usar um espaço em branco e 2) atrasar o uso do operador duplicado (duas coisas que perdi completamente).Respostas:
JavaScript (ES6),
204203200 bytesRetorna um número inteiro.
Caracteres utilizados:
+
: Adição*
: multiplicação#
: igualdaded
: duplicado-
: negativoCasos de teste
Mostrar snippet de código
Formatado e comentado
fonte
-1+-2
. Retorna 3 em vez de -3.-
deve ser aplicado-1
imediatamente.-
iria com o,2
uma vez que vem após outro operador. Talvez @HyperNeutrino possa esclarecer. O operador negativo pode ser ambíguo em algumas situações.JavaScript (ES6),
162152143150 bytesLigeiramente não destruído:
Explicação
Estou usando
*
para multiplicação eR
duplicado. Os outros operadores são os mesmos da pergunta.N
torna-se a matriz dos números (incluindo as duplicatas).Ele
replace
lida com o caso em que o sinal negativo vem após o número. Por exemplo, ele mudará1-
para- 1
e-1-
para- -1
.Dentro do
eval
,s.match
cria a matriz de operadores binários. Observe que isso sempre terá menos um elemento queN
.O resultado da função é
eval
o mapeamento dos números e operadores.Aqui está o que é
eval
ed para cada um dos casos de teste:O operador de vírgula em uma expressão JavaScript retorna o resultado de sua última expressão; portanto,
map
retorna automaticamente uma expressão utilizável.O
+
sinal é necessário antes daeval
alteraçãotrue
para1
efalse
para0
.O uso
R
da variável e do operador duplicado simplifica bastante asmap
subexpressões da.Casos de teste:
Mostrar snippet de código
fonte
replace
funciona como pretendido. Isso retorna3
para-1+--2
e acho1
que estaria correto (as1
alterações são assinadas três vezes antes de haver um segundo argumento para o+
disponível, resultando em-1 + 2
).JavaScript,
321311 bytesExperimente online!
Os cinco caracteres são os mesmos da pergunta, exceto
*
para multiplicação.O script é compactado usando o RegPack . O script original é armazenado na variável
_
após a avaliação.fonte
-1+-2
. Retorna 3 em vez de -3.-3
vez de3
?-1 + -2
é-3
, mas deve ser analisado como alternativa--1 + 2
?3
. Antes2
mesmo de chegar à pilha, o segundo-
é avaliado e, portanto, temos o1 2 +
que é de fato3
. Ah, e provavelmente você também deve editar sua resposta.Haskell , 251 bytes
Experimente online! Usa os seguintes caracteres:
a
para adição,m
multiplicação,q
igualdade,D
duplicação eN
negação. (Eu queria usare
a igualdade, mas me deparei com o problema quelex
analisa2e3
como um número.) Exemplo de uso:(#([],[])) "2a3 4m"
rendimentos20
.fonte
6502 código de máquina (C64), 697 bytes
Demonstração online
Uso
sys49152
, digite a expressão anyfix e pressione Enter.*
, todos os outros, conforme sugerido.Aqui está o código-fonte do assembler legível no estilo ca65 .
fonte
VB.NET (.NET 4.5)
615576 bytes-39 bytes graças a Felix Palmen, alterando
\r\n
para\n
Requer
Imports System.Collections.Generic
(incluído na contagem de bytes)O ponto de entrada é Function
A
, que recebe uma string como entrada e retorna aStack(Of Long)
.Símbolos:
+
*
=
-
d
Visão geral:
A função
A
pega a entrada e a simboliza. Ele usa aLong?
para fazer um total de execução para números inteiros de vários dígitos, o queNothing
significa que não estamos lendo um número inteiro no momento.A sub
E
- rotina pega a pilha de números inteiros e a fila de operadores e avalia a notação anyfix. Ele se chama recursivamente até que não haja mais ações.Declaro parâmetros globais de uma só vez para salvar bytes na declaração e na passagem de parâmetros.
O valor de retorno de
A
é definido atribuindo um valor à variável correspondenteA
.VB
True
é equivalente a-1
, para que a operação precise negar o resultado para obter o valor correto.Experimente online!
fonte
Imports
, recebo apenas uma contagem de bytes576
- você poderia ter errado?\r\n
vez de\n
, então é aí que está a discrepância.