Você recebe uma sequência composta pelos caracteres 0123456789+*()
. Você pode assumir que a string é sempre uma expressão matemática válida.
Sua tarefa é remover os parênteses desnecessários, assumindo que a multiplicação tenha maior prioridade que a adição.
Os parênteses devem ser removidos somente quando não forem necessários estruturalmente :
- por causa da multiplicação maior prioridade:
3+(4*5)
=>3+4*5
- por causa da multiplicação ou adição de adição:
3*(4*5)
=>3*4*5
- quando são redundantes em torno de uma expressão:
3*((4+5))
=>3*(4+5)
Os parênteses devem ser mantidos quando puderem ser simplificados devido a valores numéricos específicos:
1*(2+3)
não deve ser simplificado para1*2+3
0*(1+0)
não deve ser simplificado para0*1+0
Exemplos:
(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
deve ser um caso de teste interessante (para o qual minha solução atualmente falha).(2+2)*1
Respostas:
Mathematica,
1059791 bytes-6 bytes graças a Roman !
Substitui
+
e*
por~~
(StringExpression
) e**
(NonCommutativeMultiply
), respectivamente, avalia, especifica e substitui os operadores novamente.fonte
StringExpression
vez deDot
e removendo a" "->""
cláusula:a=StringReplace;ToString@ToExpression@a[#,{"*"->"**","+"->"~~"}]~a~{" ** "->"*","~~"->"+"}&
JavaScript (ES6) 163
178Editar 15 bytes salvos thx @IsmaelMiguel
Menos golfe
Teste
fonte
y.indexOf('+')
vez dey.indexOf`+`[...]
? (adicionado [...] para evitar tropeçar na formatação) Foi desse jeito?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=
,=='*'
e outros bits repetidos. Além disso, não é~y.indexOf('+')<0
o mesmo que~y.indexOf('+')
? Como o único valorindexOf()
retornado que é avaliado como falso-1
, é<0
redundante. Ou, se eu entendi errado, você poderia fazery.indexOf('+')>1
<0
porcaria remanescente da versão não destruída e deve ser removida. 2: pensando novamente, ofor
pode ser revisado para ser incluído na parte repetida. Obrigado novamenteImplementação Python3 + PEG em Python , 271 bytes
Há um tempo atrás eu fiz uma implementação PEG em Python . Eu acho que posso usar isso aqui.
Analisa a expressão em uma árvore e só mantém parênteses se o filho for adição e o pai for multiplicação.
fonte
Perl, 132 bytes
Origem de 129 bytes + 3 para o
-p
sinalizador:Usando:
fonte
Ruby,
140130 bytesOrigem de 127 bytes + 3 para o
-p
sinalizador:E não destruído:
fonte
0 while
sintaxe?expr while cond
é equivalente awhile cond; expr; end
. Aqui, eu só quero executarcond
repetidamente e na verdade não tenho um corpo em loop. Normalmente, alguém escreveria isso comowhile cond; end
ou talvez,loop{ break unless cond }
mas0 while cond
tem menos bytes. O0
não faz nada; está lá porque a forma curta do loop while requer um corpo.Retina, 155 bytes
Experimente online!
Verifique todos os casos de teste de uma só vez.
Explicação
O principal é este código:
Essa regex pode corresponder a qualquer sequência na qual os colchetes estejam balanceados, por exemplo,
1+(2+(3))+4
ou2+3
.Para facilitar a explicação, deixe esse regex
B
.Além disso, vamos usar
<
e>
para os colchetes, bem comop
em
para\+
e\*
.O código se torna:
As duas primeiras linhas correspondem a colchetes que consistem apenas em multiplicação, por exemplo,
(1*2*3)
ou mesmo(1*(2+3)*4)
. Eles são substituídos pelo conteúdo interno.As duas últimas linhas correspondem a colchetes que não são precedidos e que não são seguidos por multiplicação. Eles são substituídos pelo conteúdo interno.
O inicial
{`
significa "substituir até idempotente", significando que as substituições são feitas até que não correspondam mais ou sejam substituídas por elas mesmas.Nesse caso, as substituições são feitas até que não correspondam mais.
fonte
1*(2*(3+4)*5)*6
.(1*(2+3)+4)*5
Python 3,
274269359337336 bytesEsse método basicamente remove todos os parênteses possíveis e verifica se ele ainda avalia o mesmo.
Equipamento de teste
Atualizações
re
libl
) lambdafonte
1*(2+3)
, porque o OP disse para não simplificar para casos especiais de números. Boa resposta embora; isso tem o meu voto positivo.PHP, 358 bytes
Não é uma duração impressionante, é o que recebo por adotar uma abordagem menos que ótima (e usar uma linguagem que não seja ótima).
Retira um par de colchetes e avalia a expressão resultante. Se o resultado for o mesmo que o original, ele será adicionado a um mapa de expressões válidas e se repetirá até que nenhuma nova expressão seja encontrada. Em seguida, imprime a expressão válida mais curta.
Quebra quando o resultado da expressão aumenta e lança a notação de duplo / expoente.
fonte
Prolog (SWI) ,
122118 bytesExperimente online!
Define um predicado
//2
que remove parênteses do valor da string do primeiro argumento e gera uma string através do segundo argumento. Se a entrada pudesse ser em termos de prólogo, isso teria apenas8177 bytes de definição+/2
sem ter que lidar com os verbos detalhadosterm_string/2
, mas muitos parênteses desnecessários simplesmente não existiriam para começar dessa maneira, portanto seria bem próximo de trapacear, pois tudo o que+/2
faz é lidar com associatividade.Tentei usar
=../2
para tudo isso, mas ficou muito mais tempo, porque um operador de três bytes que trabalha com listas não é exatamente conciso:Prolog (SWI) , 124 bytes
Experimente online!
fonte