Otrzymujesz ciąg złożony ze znaków 0123456789+*()
. Możesz założyć, że ciąg jest zawsze prawidłowym wyrażeniem matematycznym.
Twoim zadaniem jest usunięcie niepotrzebnych nawiasów, zakładając, że mnożenie ma wyższy priorytet niż dodawanie.
Nawiasy należy usuwać tylko wtedy, gdy nie są potrzebne strukturalnie :
- z powodu zwielokrotnienia wyższy priorytet:
3+(4*5)
=>3+4*5
- z powodu asocjacji mnożenia lub dodawania:
3*(4*5)
=>3*4*5
- gdy są zbędne wokół wyrażenia:
3*((4+5))
=>3*(4+5)
Nawiasy należy przechowywać, gdy można je uprościć ze względu na określone wartości liczbowe:
1*(2+3)
nie należy tego upraszczać1*2+3
0*(1+0)
nie należy tego upraszczać0*1+0
Przykłady:
(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
powinien być ciekawym testem (dla którego moje rozwiązanie obecnie zawodzi).(2+2)*1
Odpowiedzi:
Mathematica,
1059791 bajtów-6 bajtów dzięki Romanowi !
Zastępuje
+
oraz*
z~~
(StringExpression
) i**
(NonCommutativeMultiply
), odpowiednio, ocenia je, stringifies ją i zastępuje operatorów powrotem.źródło
StringExpression
zamiastDot
i usuwaniu" "->""
klauzuli:a=StringReplace;ToString@ToExpression@a[#,{"*"->"**","+"->"~~"}]~a~{" ** "->"*","~~"->"+"}&
JavaScript (ES6) 163
178Edytuj 15 bajtów zapisanych dzięki @ IsmaelMiguel
Mniej golfa
Test
źródło
y.indexOf('+')
zamiasty.indexOf`+`[...]
? ([...] dodane, aby uniknąć potknięcia się o formatowanie)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=
,=='*'
i innych powtarzających się bitów. Czy to nie~y.indexOf('+')<0
to samo, co~y.indexOf('+')
? Ponieważ jedynąindexOf()
zwracaną wartością, która zwraca wartość fałszowania-1
,<0
wydaje się zbędna. Lub, jeśli źle to zrozumiem, możesz to zrobićy.indexOf('+')>1
<0
to bzdura pozostała z wersji bez golfa i powinna zostać usunięta. 2: myśląc jeszcze raz,for
można je zmienić, aby uwzględnić je w powtarzanej części.Implementacja Python3 + PEG w Pythonie , 271 bajtów
Jakiś czas temu zrobiłem implementację PEG w Pythonie . Chyba mogę tego tutaj użyć.
Przetwarza wyrażenie na drzewo i zachowuje nawiasy tylko wtedy, gdy dziecko jest dodawaniem, a rodzic jest mnożeniem.
źródło
Perl, 132 bajty
Źródło 129 bajtów + 3 dla
-p
flagi:Za pomocą:
źródło
Rubinowy,
140130 bajtówŹródło 127 bajtów + 3 dla
-p
flagi:I bez golfa:
źródło
0 while
składnią?expr while cond
jest równoważne zwhile cond; expr; end
. Tutaj chcę tylko występowaćcond
wielokrotnie i tak naprawdę nie mam pętli. Zwykle pisze się to jakowhile cond; end
lub być może,loop{ break unless cond }
ale0 while cond
ma mniej bajtów.0
Nic nie robi; jest tam tylko dlatego, że krótka forma pętli while wymaga ciała.Siatkówka, 155 bajtów
Wypróbuj online!
Zweryfikuj wszystkie przypadki testowe jednocześnie.
Wyjaśnienie
Najważniejsze jest ten kod:
Ten regex może pasować do dowolnego łańcucha, w którym nawiasy są zrównoważone, np .
1+(2+(3))+4
Lub2+3
.Dla ułatwienia wyjaśnienia niech to wyrażenie regularne będzie
B
.Użyjmy
<
i>
zamiast tego w nawiasach, a takżep
im
dla\+
i\*
.Kod staje się:
Pierwsze dwie linie pasują do nawiasów, które składają się tylko z mnożenia, np.
(1*2*3)
Lub nawet(1*(2+3)*4)
. Są one zastępowane przez ich zawartość w środku.Ostatnie dwa wiersze pasują do nawiasów, które nie są poprzedzone i po których nie następuje mnożenie. Są one zastępowane przez ich zawartość w środku.
Początkowy
{`
oznacza „zamień aż do idempotent”, co oznacza, że zamiany są wykonywane, dopóki nie będą już pasować lub zostaną zastąpione przez siebie.W takim przypadku zamiany są wykonywane, dopóki nie będą już pasować.
źródło
1*(2*(3+4)*5)*6
.(1*(2+3)+4)*5
Python 3,
274269359337336 bajtówTa metoda zasadniczo usuwa każdą możliwą parę nawiasów i sprawdza, czy nadal ocenia to samo.
Uprząż testowa
Aktualizacje
re
libl
lambda length ( )źródło
1*(2+3)
, ponieważ OP powiedział, aby nie upraszczać dla przypadków specjalnych. Dobra odpowiedź; to moje zdanie.PHP, 358 bajtów
Nie imponująca długość, to właśnie otrzymuję za przyjęcie mniej niż optymalnego podejścia (i użycie mniej niż optymalnego języka).
Usuwa parę nawiasów, a następnie analizuje wynikowe wyrażenie. Jeśli wynik jest taki sam jak oryginał, dodaje go do mapy prawidłowych wyrażeń i powtarza się, dopóki nie można znaleźć nowych wyrażeń. Następnie drukuje najkrótsze prawidłowe wyrażenie.
Łamie się, gdy wynik wyrażenia staje się duży i wyświetla się rzut notacji podwójnej / wykładniczej.
źródło
Prolog (SWI) ,
122118 bajtówWypróbuj online!
Definiuje predykat,
//2
który usuwa nawiasy z wartości ciągu pierwszego argumentu i wysyła ciąg znaków przez drugi argument. Gdyby dane wejściowe mogły być wyrażone w kategoriach Prolog, byłoby to tylko8177 bajtów definiujących+/2
bez konieczności zajmowania się gadatliwościąterm_string/2
, ale wiele niepotrzebnych nawiasów po prostu nie istniałoby od tego momentu, więc byłoby to bardzo bliskie oszustwa, ponieważ wszystko, co+/2
robi, to radzenie sobie ze stowarzyszeniem.Próbowałem użyć tego
=../2
wszystkiego, ale wyszło ono znacznie dłużej, ponieważ trzy bajtowy operator, który działa z listami, nie jest zbyt zwięzły:Prolog (SWI) , 124 bajty
Wypróbuj online!
źródło