Quylthulg est un langage de Chris Pressey qui tente de résoudre le problème de la notation infixe en utilisant ce qu'il appelle panfix :
comme postfix, panfix ne nécessite pas le déploiement de dispositifs arcanes tels que des parenthèses pour remplacer une priorité d'opérateur par défaut. En même temps, panfix permet de spécifier les termes dans le même ordre et la même manière que infix, une notation incontestablement naturelle et intuitive pour ceux qui s'y sont habitués.
Comment obtenez-vous la commodité de la notation infixe avec l’ambiguïté du préfixe ou du suffixe? Utilisez les trois, bien sûr!
=y=+*3*x*+1+=
Plus formellement, +
soit un opérateur, et a
et des b
expressions. Ensuite , (a+b)
est une expression de infix valide (parenthésée), la représentation panfix de cette expression est +a+b+
, où la juxtaposition représente la concaténation.
Votre objectif est de prendre une chaîne panfix et de la convertir en infixe entièrement entre parenthèses:
(y=((3*x)+1))
Par souci de simplicité, nous apporterons les modifications suivantes:
- Les opérateurs ne peuvent être composés que de deux caractères uniques (vous pouvez en choisir un, mais ici je vais utiliser
*
et+
). - Il n'y a qu'un seul littéral, qui consiste en un autre caractère distinct (vous pouvez en choisir un, mais ici je vais l'utiliser
_
). - L'entrée sera une expression panfix bien formée.
Pour la complexité , nous ferons le changement suivant:
- Les opérateurs peuvent être constitués de n'importe quel nombre positif de caractères, pas d'un seul.
Cela rend le défi plus difficile car vous ne pouvez pas nécessairement déterminer comment une sous-chaîne donnée de caractères d'opérateur est partitionnée sans regarder le reste de la chaîne.
Voici une implémentation de référence pour le défi, gracieuseté de @ user202729.
Cas de test
format: input -> output
+*+_*+_*+++_+*+_*+_*+++ -> ((_*+_)+(_+(_*+_)))
**++*+***++_+_++_+*++*+***_*++*+*****_**_*_*** -> ((((_+_)+_)*++*+***_)*(_*(_*_)))
***_**_***_* -> ((_**_)*_)
+_+_+ -> (_+_)
*+*+++**+***+++++_*+*+++**+***+++++_*+*+++**+***+++++ -> (_*+*+++**+***+++++_)
*++++*+*_*_*+*+++****+_++****+_++****++*+*+++_*+++ -> (((_*_)+*+(_++****+_))*+++_)
+**+_*+_*+*_*+*_*+*_+*_+**+ -> (((_*+_)*_)+(_*(_+*_)))
+**+++++_+++++_+++++*_*+*+_++++++_+++++_+++++++* -> (((_+++++_)*_)+*(_+(_+++++_)))
+*+*+_+*+_+*+*_*+*_*+*+_+*+_+*+*+ -> (((_+*+_)*_)+(_*(_+*+_)))
**_**_**_*_****_* -> ((_*(_*(_*_)))*_)
J'ai utilisé ce programme pour générer des chaînes d'infixes pour ce défi (la conversion en panfix était triviale, mais pas l'inversion).
**_**_**_*_****_*
. Les réponses que j'ai testées ont toutes échoué.(_ + _)
?Réponses:
Prolog (SWI) ,
194163octetsEnregistré un énorme 31 octets en utilisant cette astuce de 0 ' !
L'opérateur
^
prend pour son argument de gauche une chaîne contenant une expression panfix et définit son argument de droite sur une chaîne contenant l'expression d'infixe entre parenthèses correspondante. Il utilisex
comme littéral à la place de_
.Essayez-le en ligne!
Explication
Puisque Prolog est un langage déclaratif, il suffit de décrire la relation entre un panfix et une expression entre parenthèses.
L'explication utilise cette version légèrement non golfée:
Notre production principale est
parenthesize
, qui prend une expression panfixX
sous forme de chaîne et envoie l'expression infixe entre parenthèses correspondanteP
sous forme de chaîne. Il utilisestring_chars
pour convertir la chaîne d'entrée en une liste de caractères, puis la transmet simplement àexpr
.expr
prend une liste de caractèresL
, analyse la première expression panfix qu'il trouveL
et envoie l'équivalent entre parenthèsesX
et le reste de la liste de caractèresR
. Il existe deux types d'expressions possibles:L
estx
, alors l'expression estx
et le reste est tout après lex
.O
(voiroper
ci - dessous); analyser une expressionY
; analyser àO
nouveau; analyser une autre expressionZ
; et analyserO
une troisième fois. Le reste est tout après la troisième instance deO
. L'expression est le résultat de la jonctionY
,O
etZ
, entourée de parenthèses, en une chaîne.oper
prend une liste de caractères, où le premier caractère estC
et le reste sontT
; il analyse un opérateur (c'est-à-dire une séquence d'un ou plusieurs caractères d'opérateur) et envoie l'opérateurO
et le reste de la liste de caractèresR
. Pour former un opérateur, le caractèreC
doit être autre chose quex
; aussi, soitP
doit être analysable à partir duT
resteR
; dans ce cas,O
est la concaténation deC
etP
; ou,O
est le caractère uniqueC
; dans ce cas,R
c'est justeT
.Un exemple concret
Prenons l'entrée
+*+x+x++*x+*
pour un exemple.+*+x+x++*x+*
. Cela ne commence pas parx
, donc nous analysons un opérateur depuis le début.oper
analysera le plus grand opérateur possible, nous essayons donc+*+
.x+x++*x+*
. Cela doit êtrex
.+*+
partir de+x++*x+*
. Cependant, cela échoue .+*
place.+x+x++*x+*
. Cela ne commence pas parx
, nous devons donc analyser un opérateur.+
.x+x++*x+*
. Cela doit êtrex
.+
nouveau+x++*x+*
.x++*x+*
. Cela doit êtrex
.+
nouveau à partir de++*x+*
.(x+x)
.+*
nouveau l'opérateur à partir de+*x+*
.x+*
. Cela doit êtrex
.+*
nouveau à partir de+*
.((x+x)+*x)
.Puisqu'il ne reste plus de caractères, nous avons réussi à traduire l'expression.
la source
Perl,
7860585750 octetsComprend
+1
pourp
Utilise
1
pour+
et2
pour*
(ou en fait n'importe quel chiffre fonctionne pour n'importe quel opérateur)Pour des tests pratiques par rapport aux exemples donnés, vous pouvez utiliser ceci qui effectue les traductions et la suppression d'espace pour vous:
la source
Clean ,
200192189 octetsEssayez-le en ligne!
Définit la fonction
f
, en prenantString
et en retournant un singleton[String]
avec le résultat à l'intérieur.Quelques trucs sympas:
_
la source
Retina 0.8.2 , 138 octets
Essayez-le en ligne! Link inclut les cas de test les plus rapides. Explication: Le moteur d'expression régulière utilise le retour arrière pour diviser la chaîne en jetons qui sont ensuite poussés ou extraits du
i
groupe d'équilibrage. Il y a une série d'au moins un opérateur poussé au début avant la première variable. Après une variable, au moins un opérateur est sauté, auquel cas un opérateur poussé exécuté ou une autre variable est légal. Les opérateurs sont poussés vers le groupe en double afin qu'ils puissent être sautés correctement. Exemple:Malheureusement, cela ne nous aide pas à capturer les résultats afin de les mettre entre parenthèses, de sorte que l'opérateur externe est mis en correspondance manuellement. Les crochets sont ajoutés de l'extérieur vers l'intérieur, donc la première étape enveloppe l'expression entière entre crochets et la dernière étape les supprime maintenant qu'ils se sont propagés jusqu'aux variables.
la source
**_**_**_*_****_*
.Haskell ,
167166 octetsEssayez-le en ligne! Exemple d'utilisation:
head.e "**_**_**_*_****_*"
rendements((_*(_*(_*_)))*_)
. Tous les caractères sauf_
sont interprétés comme des opérateurs,_
dénote lui - même un identifiant.la source
Python 3, 226 octets
Définit une fonction anonyme nommée
R
.Essayez-le en ligne!
la source
_*+
; ce sont exactement ceux qui ont été utilisés dans l'exemple. Vous pourrez peut-être l'utiliser pour jouer à vos regex (par exemple en utilisant\d
au lieu de[*+]
).