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
0o1.
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, 10se 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, 5se 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 []. 10se 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

0y1?×+"10 10en 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-1inmediatamente.-iría con el2ya 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 yRpara duplicar. Los otros operadores son los mismos que en la pregunta.Nse convierte en la matriz de los números (incluidos los duplicados).El
replacemaneja el caso donde el signo negativo viene después del número. Por ejemplo, se cambiará1-a- 1y-1-a- -1.Dentro de
eval,s.matchcrea la matriz de operadores binarios. Tenga en cuenta que esto siempre tendrá uno menos elementos queN.El resultado de la función es
evalla asignación de los números y operadores.Esto es lo que se
evaledita 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
mapautomáticamente devuelve una expresión utilizable.El
+signo es necesario antesevalde cambiartruea1yfalsepara0.Usar
Rtanto la variable como el operador duplicado simplifica enormemente lamapsubexpresiones de.Casos de prueba:
Mostrar fragmento de código
fuente
replacefuncione como estaba previsto. Esto devuelve3para-1+--2y creo que1sería correcto (los1cambios 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.-3lugar de3?-1 + -2es-3, pero ¿debería analizarse como en su--1 + 2lugar?3.2Incluso 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:
apara sumar,mmultiplicar, igualarq,Dduplicar yNnegar. (Quería usarepara igualdad, pero me encontré con el problema que selexanaliza2e3como 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\na\nRequiere
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:
+*=-dVisión general:
La función
Atoma la entrada y la tokeniza. Utiliza aLong?para hacer un total acumulado para enteros de varios dígitos, queNothingsignifica que actualmente no estamos leyendo un entero.La subrutina
Etoma 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
Ase establece asignando un valor a la variable coincidenteA.VB
Truees 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\nlugar de\n, así que ahí es donde está la discrepancia.