En la notación de prefijo, el operador viene antes que los argumentos, por lo que puede imaginar que el operador llama a lo next()
que se llama de forma recursiva. En notación infija, el operador va entre los argumentos, por lo que puede imaginarlo simplemente como un árbol de análisis. En la notación postfix, el operador viene después de los argumentos, por lo que puede imaginarlo como basado en la pila.
En cualquier notación, el operador puede ir a cualquier parte * . Si aparece un operador y no hay suficientes argumentos, entonces el operador espera hasta que haya suficientes argumentos. Para este desafío, debe implementar un evaluador anyfix muy básico. (Tenga en cuenta que anyfix es un lenguaje recreativo que abandoné con el que puede jugar aquí o consultar aquí )
Deberá admitir los siguientes comandos:
(Arity 1)
- duplicar
- negativo
(Arity 2)
- adición
- multiplicación
- igualdad: devoluciones
0
o1
.
Puede elegir usar cinco símbolos que no sean espacios en blanco para estos comandos. Con fines demostrativos, usaré "
como duplicado, ×
como multiplicación y +
como suma.
Para literales, solo necesita admitir enteros no negativos, pero su intérprete debe poder contener todos los enteros (dentro del rango de enteros (razonable) de su idioma).
Vamos a echar un vistazo a un ejemplo: 10+5
. El almacenamiento debe comportarse como una pila, no como una cola. Entonces, primero, la pila comienza en []
, y la lista de operadores en cola comienza en []
. Luego, 10
se evalúa el literal que hace la pila [10]
. A continuación, +
se evalúa el operador , que requiere dos argumentos. Sin embargo, solo hay un argumento en la pila, por lo que se convierte en la lista de operadores en cola ['+']
. Luego, 5
se evalúa el literal que hace la pila [10, 5]
. En este punto, el operador '+'
puede ser evaluado para que así sea, haciendo que la pila [15]
y la cola[]
.
El resultado final debe ser [15]
de + 10 5
, 10 + 5
, y 10 5 +
.
Vamos a echar un vistazo a un ejemplo más difícil: 10+"
. La pila y la cola comienzan como []
y []
. 10
se evalúa primero lo que hace la pila [10]
. A continuación, +
se evalúa, lo que no cambia la pila (porque no hay suficientes argumentos) y hace la cola ['+']
. Entonces, "
se evalúa. Esto puede ejecutarse inmediatamente, por lo que es así, haciendo la pila [10, 10]
. +
ahora se puede evaluar para que la pila se convierta [20]
y la cola []
. El resultado final es [20]
.
¿Qué pasa con el orden de las operaciones?
Echemos un vistazo ×+"10 10
. La pila y la cola comienzan como []
:
×
: La pila no cambia y la cola se convierte['×']
.+
: La pila no cambia y la cola se convierte['×', '+']
."
: La pila no cambia y la cola se convierte['×', '+', '"']
.10
: La pila se convierte[10]
. Aunque×
debería ser el primer operador en ser evaluado, ya que aparece primero,"
puede ejecutarse inmediatamente y ninguno de los operadores antes que puede, por lo que se evalúa. La pila se convierte[10, 10]
y la cola['×', '+']
.×
ahora se puede evaluar, lo que hace que la pila[100]
y la cola['+']
.10
: La pila se convierte[100, 10]
, lo que permite+
ser evaluada. La pila se convierte[110]
y la cola[]
.
El resultado final es [110]
.
Los comandos utilizados en estas demostraciones son consistentes con los del lenguaje anyfix; sin embargo, el último ejemplo no funcionará debido a un error en mi intérprete. (Descargo de responsabilidad: sus envíos no se utilizarán en el intérprete anyfix)
Desafío
Seleccione un conjunto de 5 caracteres que no sean espacios en blanco y que no sean dígitos y cree un intérprete anyfix de acuerdo con las especificaciones anteriores. Su programa puede generar la matriz singular o el valor que contiene; se garantiza que la pila de valores solo contendrá un valor único al final de la ejecución y que la cola de operadores estará vacía al final de la ejecución.
Esto es código golf por lo que gana el código más corto en bytes.
Casos de prueba
Para estos casos de prueba, duplicado es "
, negativo es -
, suma es +
, multiplicación es ×
e igualdad es =
.
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)
Reglas
- Se aplican lagunas estándar
- Puede tomar el intérprete oficial anyfix y jugarlo si lo desea. Espera perder horriblemente.
La entrada se dará como una cadena y la salida como una matriz, un solo entero, fuera de la representación de la cadena de cualquiera. Puede suponer que la entrada solo contendrá espacios, dígitos y los 5 caracteres que elija.
* no realmente
fuente
0
y1
?×+"10 10
en los casos de prueba, o cualquier otro ejemplo que esté 1) usando un espacio en blanco y 2) retrasando el uso del operador duplicado (dos cosas que omití por completo).Respuestas:
JavaScript (ES6),
204203200 bytesDevuelve un entero.
Caracteres utilizados:
+
: adición*
: multiplicación#
: igualdadd
: duplicar-
: negativoCasos de prueba
Mostrar fragmento de código
Formateado y comentado
fuente
-1+-2
. Devuelve 3 en lugar de -3.-
debe aplicarse-1
inmediatamente.-
iría con el2
ya que viene después de otro operador. Quizás @HyperNeutrino pueda aclarar. El operador negativo puede ser ambiguo en algunas situaciones.JavaScript (ES6),
162152143150 bytesLigeramente incólume:
Explicación
Estoy usando
*
para multiplicar yR
para duplicar. Los otros operadores son los mismos que en la pregunta.N
se convierte en la matriz de los números (incluidos los duplicados).El
replace
maneja el caso donde el signo negativo viene después del número. Por ejemplo, se cambiará1-
a- 1
y-1-
a- -1
.Dentro de
eval
,s.match
crea la matriz de operadores binarios. Tenga en cuenta que esto siempre tendrá uno menos elementos queN
.El resultado de la función es
eval
la asignación de los números y operadores.Esto es lo que se
eval
edita para cada uno de los casos de prueba:El operador de coma en una expresión de JavaScript devuelve el resultado de su última expresión, por lo que
map
automáticamente devuelve una expresión utilizable.El
+
signo es necesario anteseval
de cambiartrue
a1
yfalse
para0
.Usar
R
tanto la variable como el operador duplicado simplifica enormemente lamap
subexpresiones de.Casos de prueba:
Mostrar fragmento de código
fuente
replace
funcione como estaba previsto. Esto devuelve3
para-1+--2
y creo que1
sería correcto (los1
cambios firman tres veces antes de que haya un segundo argumento de la+
disposición, dando como resultado-1 + 2
).JavaScript,
321311 bytesPruébalo en línea!
Los cinco caracteres son los mismos que en la pregunta, excepto
*
para la multiplicación.El script se comprime usando RegPack . El script original se almacena en la variable
_
después de la evaluación.fuente
-1+-2
. Devuelve 3 en lugar de -3.-3
lugar de3
?-1 + -2
es-3
, pero ¿debería analizarse como en su--1 + 2
lugar?3
.2
Incluso antes de llegar a la pila,-
se evalúa el segundo y, por lo tanto, tenemos1 2 +
cuál es realmente3
. Ah, y probablemente también tengas que editar tu respuesta.Haskell , 251 bytes
Pruébalo en línea! Utiliza los siguientes caracteres:
a
para sumar,m
multiplicar, igualarq
,D
duplicar yN
negar. (Quería usare
para igualdad, pero me encontré con el problema que selex
analiza2e3
como un número). Ejemplo de uso:(#([],[])) "2a3 4m"
rendimientos20
.fuente
Código de máquina 6502 (C64), 697 bytes
Demostración en línea
Uso
sys49152
, luego ingrese la expresión anyfix y presione Intro.*
, todos los demás como se sugiere.Aquí está el código fuente legible del ensamblador de estilo ca65 .
fuente
VB.NET (.NET 4.5)
615576 bytes-39 bytes gracias a Felix Palmen al cambiar
\r\n
a\n
Requiere
Imports System.Collections.Generic
(incluido en el recuento de bytes)El punto de entrada es Function
A
, que toma una cadena como entrada y devuelve aStack(Of Long)
.Símbolos:
+
*
=
-
d
Visión general:
La función
A
toma la entrada y la tokeniza. Utiliza aLong?
para hacer un total acumulado para enteros de varios dígitos, queNothing
significa que actualmente no estamos leyendo un entero.La subrutina
E
toma la pila de enteros y la cola de operadores, y evalúa la notación anyfix. Se llama recursivamente hasta que no quedan acciones.Declaro parámetros globales de una vez para guardar bytes en la declaración y el paso de parámetros.
El valor de retorno de
A
se establece asignando un valor a la variable coincidenteA
.VB
True
es equivalente a-1
, de modo que la operación tiene que negar el resultado para obtener el valor correcto.Pruébalo en línea!
fuente
Imports
, solo obtengo un recuento de bytes576
: ¿podría haber contado mal?\r\n
lugar de\n
, así que ahí es donde está la discrepancia.