Estaba navegando por esolangs y encontré este idioma: https://github.com/catseye/Quylthulg .
Una cosa interesante sobre este lenguaje, es que no usa prefijo, postfix o infix, usa los tres , llamándolo notación "panfix".
Aquí hay un ejemplo. Para representar infija normales 1+2
en panfix, se convierte en: +1+2+
. Observe cómo el operador está antes, en el medio y después de los operandos. Otro ejemplo es (1+2)*3
. Esto se convierte *+1+2+*3*
. Observe nuevamente cómo *
está en los tres lugares con respecto a los operandos +1+2+
y 3
.
El reto
Como habrás adivinado, tu tarea en este desafío es convertir una expresión de infijo a panfix.
Algunas aclaraciones:
- Solo tiene que lidiar con las cuatro operaciones básicas:
+-*/
- No tendrá que lidiar con las versiones unarias de esas, solo binarias
- Tienes que lidiar con paréntesis
- Asuma las reglas de precedencia normales de
*/
entonces+-
y la asociatividad izquierda para todos ellos. - Los números serán enteros no negativos
- Opcionalmente, puede tener espacios tanto en la entrada como en la salida
Casos de prueba
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-*
Este es el código de golf , por lo que gana el código más corto en bytes
fuente
S.split``
debería serlo[...S]
, aunque en realidad puede ayudar hacer coincidir/\d+|./g
por adelantado y trabajar en eso en su lugar.Mathematica
203195 bytesEs probable que esto sea menos que eficiente, pero parece hacer el trabajo.
Esta es una función anónima que toma una expresión real y devuelve una cadena con notación panfix. Mathematica clasifica la precedencia de los operadores en el momento del análisis, en lugar del tiempo de evaluación, por lo que el anidamiento debe ser automáticamente correcto. Al menos los casos de prueba funcionan como se esperaba.
Explicación: Es bastante fácil interpretar toda la expresión como un árbol, así:
En esta etapa, los operadores (cada nodo que no es una hoja) ya no son operadores, en realidad se han convertido en cadenas como
"+"
. Los enteros también se convierten en cadenas. Luego, una regla de reemplazo repetida convierte cada nodo que tiene exactamente dos hojas en el panfixparent-leaf1-parent-leaf2-parent
. Después de algunas iteraciones, el árbol se reduce a una sola cadena.La principal pérdida en el recuento de bytes es que Mathematica interpreta
Y esto sucede también en el momento del análisis.
Golfed un poco hacia abajo, ya que el patrón
a_/b_
también se interpreta comoa_ * (b_)^(-1)
. También algunas optimizaciones menores en otros lugares.fuente
Prólogo, 87 bytes
Esta es una función (principalmente porque escribir un programa completo tiene niveles de pesadilla de repetitivo en Prolog; normalmente, incluso si compila un programa, produce un REPL cuando se ejecuta), llamado
p
. Toma entrada de stdin y salidas en stdout. Tenga en cuenta que debe agregar un punto a la entrada, lo cual es una desafortunada consecuencia de la forma en que funcionan las rutinas de entrada de Prolog (usan puntos en la entrada de la misma manera que otros idiomas usan líneas nuevas); eso podría o no descalificar la respuesta.Explicación
Los operadores aritméticos, en Prolog, normalmente se interpretan como constructores de tuplas . Sin embargo, obedecen las mismas reglas de precedencia que los operadores aritméticos reales en los que se basan; se puede formar tuplas con la notación infija, y
+
y-
se unen menos fuertemente que*
y/
, con preferencia tomada izquierda a derecha dentro de un grupo. Esto es exactamente lo que pide la pregunta; por lo tanto, podemos leer una tupla anidada completa de la entrada, y ya tiene la estructura correcta. Eso es lo quep
hace.Luego, necesitamos convertirlo a notación panfix.
x
convierte la entrada en una lista panfixed de los constructores y los números enteros, y puede ser leído como una frase Inglés casi directamente: "x
deT
es: siT
es una tupla con el constructorO
y los argumentosA
,B
y, a continuaciónO
,x
deA
,O
,x
deB
,O
, de lo contrarioT
". Finalmente, solo tenemos que imprimir la lista sin separadores (es decir, usarmaplist
para llamarwrite
a cada elemento de la lista).Utilicé SWI-Prolog para probar esto, porque mi versión de GNU Prolog aún no tiene
maplist
(aparentemente se ha agregado a una versión más nueva), pero generalmente debería ser bastante portátil entre las implementaciones de Prolog.fuente