Descripción
El lenguaje de programación imaginario (IPL) utiliza la notación inversa polaca. Tiene los siguientes comandos:
- i - ingrese el número y empújelo a la pila
- o - salida no destructiva en la parte superior de la pila (el número permanece en la pila)
- d - descartar la parte superior de la pila
- número entero : empuje este número a la pila
- + - * - saca dos números de la pila, realiza la operación correspondiente y retrasa el resultado. No hay división en IPL.
IPL funciona solo con enteros y se utiliza para cálculos simples. Un programa de IPL se escribe en una línea y se separa por espacios. La cadena vacía es un programa de IPL válido.
Programa de IPL:
i i + o
Introduce dos números, los suma y genera el resultado.
Los números de entrada y los enteros que se pueden empujar a la pila están en el rango [-999, 999], sin embargo, la salida puede ser cualquiera. Sin embargo, si su idioma no admite números grandes, está bien.
Formato de entrada / salida
Puede elegir cualquier formato de entrada / salida siempre que sea claro para entender y leer / escribir: cadena, lista, tokens, etc.
Tarea
Le dan algún programa de IPL, necesita optimizarlo (reducir la longitud):
i 12 + 3 + o d 2 3 + d
Después de la optimización se convertirá
i 15 + o
No tiene que conservar el estado de la pila, pero la cantidad de entradas y salidas y su orden deben coincidir con el programa original y optimizado.
Entonces, el programa IPL:
-40 i * 2 * o i + 3 1 + o i 2 *
Después de la optimización se convertirá
i -80 * o i 4 o i
o
-80 i * o i 4 o i
(tenga en cuenta que debe guardar todas las entradas, incluso si son irrelevantes).
No debe haber una codificación rígida para los casos de prueba, el código debe funcionar en cualquier programa de IPL arbitrario y producir el programa de IPL más corto posible que cumpla con los requisitos.
Tanteo
Código predeterminado de puntuación de golf.
ACTUALIZACIÓN: cambió la puntuación a puntuación de golf de código puro, según la sugerencia de @Sanchises.
Casos de prueba:
Entrada:
(empty string)
Salida posible:
(empty string)
Entrada:
i 4 * 2 + 3 * 6 - o
Salida posible:
i 12 * o
Entrada:
1 1 + o
Salida posible:
2 o
Entrada:
i 2 + 3 + o d 2 3 + d
Salida posible:
i 5 + o
Entrada:
-40 i * 2 * o i + 3 1 + o i 2 *
Salida posible:
-80 i * o i 4 o i
Entrada:
i i 1 + i 1 + i 1 + i 1 + d d d d o
Salida posible:
i i i i i d d d d o
Entrada:
i i i 0 * * * o
Salida posible:
i i i 0 o
Entrada:
i i i 1 * * * o
Salida posible:
i i i * * o
Entrada:
i 222 + i 222 - + o
Salida posible:
i i + o
Entrada:
i 2 + 3 * 2 + 3 * 2 + 3 * i * d i 2 + 3 * i + d i o 2 + 2 - 0 * 1 o
Salida posible:
i i i i i o 1 o
Entrada:
i 1 + 2 * 1 + o
Salida posible:
i 2 * 3 + o
Entrada:
1 1 + o i 2 + 3 + o d 2 3 + d 4 i * 2 * o i + 3 1 + o i 2 * i i 1 + i 1 + i 1 + i 1 + d d d d o i i i 0 * * * o i i i 1 * * * o i 2 + i 2 - + o i 2 + 3 * 2 + 3 * 2 + 3 * i * d i 2 + 3 * i + d i o 2 + 2 - 0 * 1 o
Salida posible:
2 o i 5 + o 8 i * o i 4 o i i i i i i d d d d o i i i 0 o i i i * * * o i i + o i i i i i o 1 o
fuente
i i d o
ai o i
(la entrada está en orden y la salida está en orden) o no debe simplificarlo? (el conjunto de entradas y salidas debe estar en orden)Respuestas:
Wolfram Language (Mathematica) ,
733728690564516506513548 bytesPruébalo en línea!
Este es un recorrido de cuatro pasos que (1) reemplaza "-" con "-1 * +" para que no tengamos que lidiar con sustracciones, (2) simplifica un poco la lista de comandos, ( 3) hace una lista de todas las permutaciones de esta lista de comandos y selecciona aquellas que dan el mismo resultado cuando se analizan (ejecutan), y (4) simplifica un poco estas listas de comandos y selecciona las más cortas, después de convertir ciertas operaciones de nuevo a sustracciones
Este código es terriblemente ineficiente porque pasa por la lista de todas las permutaciones del código de entrada. Para códigos de entrada largos, no recomiendo ejecutar este código; pero mientras lo leo, no hay restricciones de tiempo de ejecución o memoria en este desafío.
Este código realiza el paso de optimización después de convertir todas las operaciones "-" a operaciones "+" con signos invertidos, y solo al final reintroduce el operador "-" cuando vuelve a convertir el código en cadenas. Esto implica, por ejemplo, que "i -1 i * + o" está correctamente optimizado para "ii - o".
Como el requisito de formato de E / S es bastante flexible, este código toma y devuelve el código como listas, donde los símbolos "+", "-", "*" están representados por p, m, t, tokens respectivamente. La conversión desde y hacia cadenas se realiza en la función de contenedor dada en TIO:
Versión sin golf, que incluye el contenedor de formato de cadena y minimiza la longitud de la cadena de código final en lugar del número de tokens, e incluye algunas sutilezas de transformación más:
Gracias a @redundancy por detectar un error: el analizador necesita un
Expand
aplicación a la salida para manejar la equivalencia distributiva. 506 → 513actualizar
Ahora también se optimiza
1 o 1 + o
para1 o 2 o
. Este fue un caso sorprendentemente difícil e hizo que el código fuera mucho más lento. 513 → 548fuente
i i 1 + i 1 + i 1 + i 1 + d d d d o
.i 2 * i 2 * + o
debería producir una salida optimizadai i + 2 * o
, pero este código devuelve la entrada (no optimizada).