La description
Le langage de programmation imaginaire (IPL) utilise la notation inversée polonaise. Il a les commandes suivantes:
- i - entrez le numéro et poussez-le dans la pile
- o - sortie non destructive en haut de la pile (le nombre reste sur la pile)
- d - jeter le haut de la pile
- nombre entier - pousser ce nombre dans la pile
- + - * - pop deux nombres de la pile, effectuez l'opération correspondante et repoussez le résultat. Il n'y a pas de division dans IPL.
L'IPL ne fonctionne qu'avec des entiers et est utilisé pour des calculs simples. Un programme IPL est écrit sur une ligne et séparé par des espaces. La chaîne vide est un programme IPL valide.
Programme IPL:
i i + o
Saisit deux nombres, les additionne et produit le résultat.
Les nombres d'entrée et les entiers pouvant être poussés vers la pile sont dans la plage [-999, 999], mais la sortie peut être quelconque. Si votre langue ne prend pas en charge les grands nombres, tout va bien.
Format d'entrée / sortie
Vous pouvez choisir n'importe quel format d'entrée / sortie tant qu'il est clair pour comprendre et lire / écrire: chaîne, liste, jetons, etc.
Tâche
On vous donne un programme IPL, vous devez l'optimiser (réduire la longueur):
i 12 + 3 + o d 2 3 + d
Après l'optimisation deviendra
i 15 + o
Vous n'avez pas à conserver l'état de la pile, mais la quantité d'entrées et de sorties et leur ordre doivent correspondre au programme d'origine et optimisé.
Alors programme IPL:
-40 i * 2 * o i + 3 1 + o i 2 *
Après l'optimisation deviendra
i -80 * o i 4 o i
ou
-80 i * o i 4 o i
(notez que vous devez enregistrer toutes les entrées, même si elles ne sont pas pertinentes).
Il ne devrait pas y avoir de codage en dur pour les cas de test, le code devrait fonctionner sur n'importe quel programme IPL arbitraire et produire le programme IPL le plus court possible qui réponde aux exigences.
Notation
Score par défaut du code-golf.
MISE À JOUR: modification du score en notation de golf en code pur, conformément à la suggestion de @Sanchises.
Cas de test:
Contribution:
(empty string)
Sortie possible:
(empty string)
Contribution:
i 4 * 2 + 3 * 6 - o
Sortie possible:
i 12 * o
Contribution:
1 1 + o
Sortie possible:
2 o
Contribution:
i 2 + 3 + o d 2 3 + d
Sortie possible:
i 5 + o
Contribution:
-40 i * 2 * o i + 3 1 + o i 2 *
Sortie possible:
-80 i * o i 4 o i
Contribution:
i i 1 + i 1 + i 1 + i 1 + d d d d o
Sortie possible:
i i i i i d d d d o
Contribution:
i i i 0 * * * o
Sortie possible:
i i i 0 o
Contribution:
i i i 1 * * * o
Sortie possible:
i i i * * o
Contribution:
i 222 + i 222 - + o
Sortie possible:
i i + o
Contribution:
i 2 + 3 * 2 + 3 * 2 + 3 * i * d i 2 + 3 * i + d i o 2 + 2 - 0 * 1 o
Sortie possible:
i i i i i o 1 o
Contribution:
i 1 + 2 * 1 + o
Sortie possible:
i 2 * 3 + o
Contribution:
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
Sortie possible:
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
la source
i i d o
ài o i
(l'entrée est en ordre et la sortie est en ordre) ou si vous simplifier pas? (l'ensemble des entrées et sorties doit être en ordre)Réponses:
Wolfram Language (Mathematica) ,
733728690564516506513548 octetsEssayez-le en ligne!
Il s'agit d'un tour de force en quatre étapes qui (1) remplace "-" par "-1 * +" afin que nous n'ayons pas à traiter les soustractions, (2) simplifie un peu la liste des commandes, ( 3) fait une liste de toutes les permutations de cette liste de commandes et sélectionne celles qui donnent le même résultat lors de l'analyse (exécutée), et (4) simplifie un peu ces listes de commandes et sélectionne la plus courte, après avoir reconverti certaines opérations en soustractions.
Ce code est terriblement inefficace car il passe par la liste de toutes les permutations du code d'entrée. Pour les codes d'entrée longs, je ne recommande pas d'exécuter ce code; mais comme je l'ai lu, il n'y a aucune restriction d'exécution ou de mémoire dans ce défi.
Ce code effectue l'étape d'optimisation après la conversion de toutes les opérations "-" en opérations "+" avec des signes inversés, et seulement à la fin réintroduit l'opérateur "-" lors de la reconversion du code en chaînes. Cela implique par exemple que "i -1 i * + o" est correctement optimisé en "ii - o".
Comme l'exigence de format d'E / S est assez lâche, ce code prend et renvoie le code sous forme de listes, où les symboles "+", "-", "*" sont représentés respectivement par p, m, t, jetons. La conversion de et vers des chaînes se fait dans la fonction wrapper donnée sur TIO:
Version sans golf, incluant l'encapsuleur au format chaîne et minimisant la longueur de chaîne de code finale au lieu du nombre de jetons, et incluant quelques subtilités de transformation supplémentaires:
Merci à @redundancy d'avoir attrapé un bug: l'analyseur a besoin d'un
Expand
appliqué à la sortie afin de gérer l'équivalence distributive. 506 → 513mise à jour
Maintenant , permet d' optimiser également
1 o 1 + o
à1 o 2 o
. C'était un cas étonnamment difficile et a rendu le code beaucoup plus lent. 513 → 548la source
i i 1 + i 1 + i 1 + i 1 + d d d d o
.i 2 * i 2 * + o
devrait produire une sortie optimiséei i + 2 * o
, mais ce code renvoie l'entrée (non optimisée).