Vous obtenez une chaîne composée des caractères 0123456789+*()
. Vous pouvez supposer que la chaîne est toujours une expression mathématique valide.
Votre tâche consiste à supprimer les parenthèses inutiles, en supposant que la multiplication a une priorité plus élevée que l'addition.
Les parenthèses ne doivent être supprimées que lorsqu'elles ne sont pas nécessaires structurellement :
- en raison de la multiplication de priorité plus élevée:
3+(4*5)
=>3+4*5
- en raison de la multiplication ou de l'associativité par addition:
3*(4*5)
=>3*4*5
- lorsqu'ils sont redondants autour d'une expression:
3*((4+5))
=>3*(4+5)
Les parenthèses doivent être conservées lorsqu'elles peuvent être simplifiées en raison de valeurs numériques spécifiques:
1*(2+3)
ne devrait pas être simplifié1*2+3
0*(1+0)
ne devrait pas être simplifié0*1+0
Exemples:
(4*12)+11 ==> 4*12+11
(1+2)*3 ==> (1+2)*3
3*(4*5) ==> 3*4*5
((((523)))) ==> 523
(1+1) ==> 1+1
1*(2*(3+4)*5)*6 ==> 1*2*(3+4)*5*6
1*(2+3) ==> 1*(2+3)
0*(1+0) ==> 0*(1+0)
(((2+92+82)*46*70*(24*62)+(94+25))+6) ==> (2+92+82)*46*70*24*62+94+25+6
1*(2*(3+4)*5)*6
devrait être un testcase intéressant (pour lequel ma solution échoue actuellement).(2+2)*1
Réponses:
Mathematica,
1059791 octets-6 octets grâce à Roman !
Remplace
+
et*
par~~
(StringExpression
) et**
(NonCommutativeMultiply
) respectivement, l'évalue, le stringifie et remplace les opérateurs.la source
StringExpression
au lieu deDot
, et en supprimant la" "->""
clause:a=StringReplace;ToString@ToExpression@a[#,{"*"->"**","+"->"~~"}]~a~{" ** "->"*","~~"->"+"}&
JavaScript (ES6) 163
178Modifier 15 octets enregistrés thx @IsmaelMiguel
Moins golfé
Tester
la source
y.indexOf('+')
au lieu dey.indexOf`+`[...]
? ([...] ajouté pour éviter de trébucher sur le formatage) Était-ce un bug de cette façon?a=>eval(`for(b=s=[]${_=';a!=b;a=b.replace(/'}\\(([^()]*)\\)(?=(.?))/,(x,y,z,p)=>~y.indexOf('+')<0?-s.push(b[p-1]=='*'|z=='*'?x:y):y))b=a;for(b=0${_}-\\d+/,x=>s[~x]))b=a`)
for(b=
,=='*'
et d'autres bits répétés. Aussi, n'est-ce pas~y.indexOf('+')<0
la même chose que~y.indexOf('+')
? Étant donné que la seule valeurindexOf()
renvoyée qui s'évalue à une valeur falsifiée est-1
, la<0
semble redondante. Ou, si je me trompe, vous pourriez le fairey.indexOf('+')>1
<0
merde reste de la version non golfée et doit être supprimée. 2: en y repensant, lefor
peut être révisé pour être inclus dans la partie répétée. Merci encoreImplémentation Python3 + PEG en Python , 271 octets
Il y a quelque temps, j'ai fait une implémentation PEG en Python . Je suppose que je peux l'utiliser ici.
Analyse l'expression dans un arbre et ne conserve les parenthèses que si l'enfant est l'addition et le parent la multiplication.
la source
Perl, 132 octets
129 octets source + 3 pour l'
-p
indicateur:En utilisant:
la source
Rubis,
140130 octets127 octets source + 3 pour l'
-p
indicateur:Et non golfé:
la source
0 while
syntaxe?expr while cond
est équivalent àwhile cond; expr; end
. Ici, je veux seulement jouercond
plusieurs fois et je n'ai pas de corps de boucle. Habituellement, on écrirait cela commewhile cond; end
ou peut-être,loop{ break unless cond }
mais il0 while cond
y a moins d'octets. Le0
ne fait rien; c'est juste parce que la forme courte de la boucle while nécessite un corps.Rétine, 155 octets
Essayez-le en ligne!
Vérifiez tous les cas de test à la fois.
Explication
L'essentiel est ce code:
Cette expression régulière peut correspondre à n'importe quelle chaîne dans laquelle les crochets sont équilibrés, par exemple
1+(2+(3))+4
ou2+3
.Pour la facilité d'explication, que ce regex soit
B
.Utilisons également
<
et à la>
place pour les crochets, ainsi quep
etm
pour\+
et\*
.Le code devient:
Les deux premières lignes correspondent aux parenthèses qui consistent uniquement en une multiplication, par exemple
(1*2*3)
ou même(1*(2+3)*4)
. Ils sont remplacés par leur contenu à l'intérieur.Les deux dernières lignes correspondent aux parenthèses qui ne sont pas précédées et qui ne sont pas suivies de multiplication. Ils sont remplacés par leur contenu à l'intérieur.
Le premier
{`
signifie "remplacer jusqu'à idempotent", ce qui signifie que les remplacements sont effectués jusqu'à ce qu'ils ne correspondent plus ou qu'ils soient remplacés par eux-mêmes.Dans ce cas, les remplacements sont effectués jusqu'à ce qu'ils ne correspondent plus.
la source
1*(2*(3+4)*5)*6
.(1*(2+3)+4)*5
Python 3,
274269359337336 octetsCette méthode supprime essentiellement toutes les paires de parenthèses possibles et vérifie si elle est toujours la même.
Harnais de test
Mises à jour
re
libl
) lambdala source
1*(2+3)
, car OP a dit de ne pas simplifier pour les cas de numéros spéciaux. Bonne réponse cependant; cela a mon upvote.PHP, 358 octets
Pas une longueur impressionnante, c'est ce que j'obtiens en adoptant une approche moins qu'optimale (et en utilisant un langage moins qu'optimal).
Supprime une paire de crochets, puis met à jour l'expression résultante. Si le résultat est le même que l'original, il l'ajoute à une carte d'expressions valides et se reproduit jusqu'à ce qu'aucune nouvelle expression ne soit trouvée. Imprime ensuite l'expression valide la plus courte.
Arrête lorsque le résultat de l'expression devient volumineux et s'affiche en notation double / exposant.
la source
Prolog (SWI) ,
122118 octetsEssayez-le en ligne!
Définit un prédicat
//2
qui supprime les parenthèses de la valeur de chaîne de son premier argument et génère une chaîne via son deuxième argument. Si l'entrée pouvait être en termes Prolog, cela ne serait que de8177 octets définissant+/2
sans avoir à traiter avec le verbeuxterm_string/2
, mais beaucoup de parenthèses inutiles n'auraient tout simplement pas existé pour commencer de cette façon, donc ce serait assez proche de la tricherie, car il+/2
ne s'agit que de gérer l'associativité.J'ai essayé de l'utiliser
=../2
pour tout cela, mais cela est sorti beaucoup plus longtemps, car un opérateur à trois octets qui fonctionne avec des listes n'est pas exactement concis:Prolog (SWI) , 124 octets
Essayez-le en ligne!
la source