Te dan una cadena compuesta con los caracteres 0123456789+*()
. Puede suponer que la cadena siempre es una expresión matemática válida.
Su tarea es eliminar los paréntesis innecesarios, suponiendo que la multiplicación tenga mayor prioridad que la suma.
Los paréntesis deben eliminarse solo cuando no son necesarios estructuralmente :
- debido a la multiplicación mayor prioridad:
3+(4*5)
=>3+4*5
- debido a la asociatividad de multiplicación o suma:
3*(4*5)
=>3*4*5
- cuando son redundantes alrededor de una expresión:
3*((4+5))
=>3*(4+5)
Los paréntesis deben mantenerse cuando puedan simplificarse debido a valores numéricos específicos:
1*(2+3)
no debe simplificarse a1*2+3
0*(1+0)
no debe simplificarse a0*1+0
Ejemplos:
(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
debería ser un caso de prueba interesante (por el cual mi solución falla actualmente).(2+2)*1
Respuestas:
Mathematica,
1059791 bytes-6 bytes gracias a Roman !
Reemplaza
+
y*
con~~
(StringExpression
) y**
(NonCommutativeMultiply
) respectivamente, lo evalúa, lo encadena y reemplaza los operadores.fuente
StringExpression
lugar deDot
, y eliminando la" "->""
cláusula:a=StringReplace;ToString@ToExpression@a[#,{"*"->"**","+"->"~~"}]~a~{" ** "->"*","~~"->"+"}&
JavaScript (ES6) 163
178Editar 15 bytes guardados gracias a @IsmaelMiguel
Menos golf
Prueba
fuente
y.indexOf('+')
lugar dey.indexOf`+`[...]
? ([...] agregado para evitar tropezar con el formateo) ¿Estaba fallando de esa manera?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=
,=='*'
y otras partes repetidas. Además, ¿no es lo~y.indexOf('+')<0
mismo que~y.indexOf('+')
? Dado que el único valor queindexOf()
devuelve que se evalúa como un valor falso es-1
, el<0
parece redundante. O, si me equivoqué, podrías hacerloy.indexOf('+')>1
<0
queda la basura de la versión sin golf y debe eliminarse. 2: pensando de nuevo, elfor
puede ser revisado para ser incluido en la parte repetida. Gracias de nuevoImplementación de Python3 + PEG en Python , 271 bytes
Hace un tiempo hice una implementación PEG en Python . Creo que puedo usar eso aquí.
Analiza la expresión en un árbol y solo guarda paréntesis si el hijo es una suma y el padre es una multiplicación.
fuente
Perl, 132 bytes
129 bytes fuente + 3 para
-p
bandera:Utilizando:
fuente
Ruby,
140130 bytes127 bytes fuente + 3 para
-p
bandera:Y sin golfos:
fuente
0 while
sintaxis?expr while cond
es equivalente awhile cond; expr; end
. Aquí, solo quiero realizarcond
repetidamente y en realidad no tengo un cuerpo de bucle. Por lo general, uno escribiría esto comowhile cond; end
o tal vez,loop{ break unless cond }
pero0 while cond
tiene menos bytes. El0
no hace nada; está ahí porque la forma corta del ciclo while requiere un cuerpo.Retina, 155 bytes
Pruébalo en línea!
Verifique todas las cajas de prueba a la vez.
Explicación
Lo principal es este código:
Esta expresión regular puede coincidir con cualquier cadena en la que los corchetes estén equilibrados, por ejemplo,
1+(2+(3))+4
o2+3
.Para facilitar la explicación, deje que esta expresión regular sea
B
.Además, usemos
<
y en su>
lugar para los corchetes, así comop
ym
para\+
y\*
.El código se convierte en:
Las dos primeras líneas coinciden para los corchetes que consisten en solo multiplicación, por ejemplo,
(1*2*3)
o incluso(1*(2+3)*4)
. Son reemplazados por su contenido en el interior.Las dos últimas líneas coinciden con los corchetes que no están precedidos y que no van seguidos de multiplicación. Son reemplazados por su contenido en el interior.
La inicial
{`
significa "reemplazar hasta idempotente", lo que significa que los reemplazos se realizan hasta que ya no coinciden o se reemplazan con ellos mismos.En este caso, los reemplazos se realizan hasta que ya no coinciden.
fuente
1*(2*(3+4)*5)*6
.(1*(2+3)+4)*5
Python 3,
274269359337336 bytesBásicamente, este método elimina cada par de paréntesis y verificaciones posibles para ver si aún evalúa lo mismo.
Arnés de prueba
Actualizaciones
re
libl
) lambdafuente
1*(2+3)
, porque OP dijo que no se simplificara para casos de números especiales. Buena respuesta sin embargo; Esto tiene mi voto a favor.PHP, 358 bytes
No es una longitud impresionante, eso es lo que obtengo por adoptar un enfoque menos que óptimo (y usar un lenguaje menos que óptimo).
Elimina un par de corchetes, luego evalúa la expresión resultante. Si el resultado es el mismo que el original, lo agrega a un mapa de expresiones válidas y se repite hasta que no se puedan encontrar nuevas expresiones. Luego imprime la expresión válida más corta.
Se rompe cuando el resultado de la expresión se hace grande y aparece la notación de doble / exponente.
fuente
Prólogo (SWI) ,
122118 bytesPruébalo en línea!
Define un predicado
//2
que elimina los paréntesis del valor de la cadena de su primer argumento y genera una cadena a través de su segundo argumento. Si la entrada pudiera estar en términos de Prolog, esto sería solo8177 bytes definiendo+/2
sin tener que lidiar con lo detalladoterm_string/2
, pero muchos paréntesis innecesarios simplemente no habrían existido para comenzar de esa manera, por lo que estaría muy cerca de hacer trampa, ya que todo lo que+/2
hace es manejar la asociatividad.Intenté usarlo
=../2
todo, pero salió mucho más tiempo, porque un operador de tres bytes que funciona con listas no es exactamente conciso:Prólogo (SWI) , 124 bytes
Pruébalo en línea!
fuente