Oceń dane wyrażenie omnifix.
Omnifix przypomina notację normalną matematyki, ale z dodatkowymi kopiami każdego symbolu otaczającego argumenty. Symbole zewnętrzne zastępują nawiasy, dlatego nie ma potrzeby wprowadzania dodatkowych nawiasów.
Musisz obsługiwać dodawanie, odejmowanie, mnożenie, dzielenie i dodatnie liczby rzeczywiste (liczby ujemne można zapisać -0-n-
) w rozsądnym zakresie dla twojego języka.
Plus i minus muszą być +
i -
, ale możesz użyć *
lub ×
dla czasów i /
lub ÷
do podziału. Inne rozsądne symbole będą dozwolone na żądanie.
Punkty Brownie za wyjaśnienia i dodatkowe funkcje (takie jak dodatkowe operacje, liczby ujemne, ciągi itp.) Nawet jeśli twoja odpowiedź nie ma tych funkcji, możesz pokazać, jak to możliwe.
Podaj link, aby w miarę możliwości przetestować swoje rozwiązanie.
Przykłady
Dla jasności w poniższych objaśnieniach użyto wysokiej minus ( ¯
) do wskazania liczb ujemnych. Możesz zwrócić liczby ujemne w dowolnym rozsądnym formacie.
-5-2-
→ 3
+2+×3×2×+
→ 8
( +2+×3×2×+
→ +2+6+
→ 8
)
-14--3-1--
→ 12
( -4--3-1--
→ -14-2-
→ 12
)
+2.1+×3.5×2.2×+
→ 9.8
( +2.1+×3.5×2.2×+
→ +2.1+7.7+
→ 9.8
)
×3×÷-0-6-÷2÷×
→ -9
( ×3×÷-0-6-÷2÷×
→ ×3×÷¯6÷2÷×
→ ×3ׯ3×
→ ¯9
)
÷4÷-3-÷1÷2÷-÷
→ 1.6
( ÷4÷-3-÷1÷2÷-÷
→ ÷4÷-3-0.5-÷
→ ÷4÷2.5÷
→ 1.6
)
The explanations below use high minus (`¯`) to indicate negative numbers.
Zdecydowanie kochasz APL.-
s można pomylić z-
s, a¯
s nie można pomylić z-
s.Odpowiedzi:
C # (.NET Core) ,
198 197188 bajtówWypróbuj online!
Używa
*
i/
.Funkcja rekurencyjna. Najpierw próbuje przeanalizować ciąg wejściowy jako
float
. Jeśli zawiedzie, wywołuje się rekurencyjnie, przekazując jako argumenty pierwszy i drugi operand, a następnie wykonuje wybraną operację na wynikach.źródło
IndefOf(f, 1)
może byćIndexOf(f,1)
float
Zamiast tego użyj s, użyj kodów char, jeśli je masz, prawdopodobnie możesz je skrócić za pomocą>
iw<
kilku miejscach.i+1,s.Length-i-2
na++i,s.Length+~i
.Python 3,
159158152144136135132 bajtówWypróbuj online!
Nie pozwala na liczby ujemne (choć
-0-5-
działa oczywiście) i wymaga operatorów python.źródło
while~-(l[i]in'+-*/'):i+=1;a=1
i*l,=input()
dla 152 bajtówif a:l[i]='(';i=t(t(i+1));l[i-1]=')'
zreturn-~i
dla 135 bajtów: PSiatkówka ,
290287286 bajtówWypróbuj online! Uwaga: Może tylko arytmetyki liczb całkowitych, więc niektóre przypadki testowe zostały usunięte. Akceptuje i zwraca liczby ujemne przy użyciu
¯
prefiksu. Edycja: Zapisano34 bajty dzięki @Cowsquack. Wyjaśnienie:Potrzebowałem jakiegoś sposobu obsługi zera, więc używam go
¦
jako prefiksu liczby dodatniej. Liczby są następnie konwertowane na unary.Ale liczby ujemne wymagają tylko
¯
prefiksu.Cytowanie
+
s staje się brzydkie, więc zmieniam dodawanie w odejmowanie.Jeśli wartość bezwzględna LHS odejmowania jest mniejsza niż RHS, przełącz je i neguj obie strony.
Także jeśli LHS mnożenia lub dzielenia jest ujemne, zaneguj obie strony.
Również jeśli LHS mnożenia wynosi zero, to wynik wynosi zero. Ponadto dwa minusy stanowią plus.
Ale minus i plus (lub odwrotnie) tworzą minus.
Odejmij dwie liczby tego samego znaku. Rób to wielokrotnie, aż nie pozostaną takie odejmowania.
Jeśli nadal występuje odejmowanie, znaki muszą być różne, więc dodaj liczby razem. (Ale zrób to tylko raz, ponieważ może to ponownie ujawnić odejmowanie dwóch liczb tego samego znaku).
Wykonaj mnożenie przez wielokrotne dodawanie.
Dokonaj podziału na liczby całkowite. Jeden z powyższych kroków uprości wyrażenie, więc zapętlaj wstecz, dopóki nie pozostaną żadne operacje.
Konwertuj z powrotem na dziesiętne.
źródło
+`-(([¯¦])1*)(1*)-\2\3-
,[¯¦]
może stać się¯|¦
([×÷])
;)PHP ,
116114109 bajtów-5 dzięki Martin Ender
Zastosowania
*
do mnożenia i/
dzielenia. Liczby ujemne zdarzają się, pomimo tego, że nie podejmuję żadnych konkretnych prób.Wypróbuj online!
Nieoznakowany i wyjaśniony
Wyjaśnię również wyrażenie regularne, ponieważ jest to trochę magiczne:
Po pierwsze, chcemy dopasować dowolny z czterech operatorów:
*+/-
Następnie musimy dopasować liczbę
[\d.]+
lub inne prawidłowe wyrażenie omnifix(?R)
.Następnie dopasowujemy tego samego operatora, który był na początku.
Następnie robimy to samo, co w grupie 3: dopasowujemy liczbę lub wyrażenie dookólne.
Na koniec ponownie dopasuj początkowego operatora.
Cokolwiek pasuje to zostanie zastąpione przez
($2)
. To bierze część wewnątrz otaczających operatorów i umieszcza ją w nawiasach, więc wygląda jak normalna notacja infiksowa.źródło
QuadR ,
333227 bajtów-1 dzięki Cows Quack . -5 dzięki Erikowi Outgolfer .
z argumentem / flagą
≡
Wypróbuj online!
Jest to równoważne z 40-bajtowym rozwiązaniem Dyalog APL:
Wypróbuj online!
Wyjaśnienie
(tekst w nawiasach odnosi się do Dyalog APL zamiast QuadR)
(
…){2}\2
Następujący wzór dwa razy, a całość również dwukrotnie:(.)
dowolny znak[
…]+
po którym następuje co najmniej jeden z następujących zestawów znaków:\d
d igits,¯
high minus (znak ujemny)\.
okres(
⎕R
jest R eplaced z :)(
{
…}
Wynik następującej anonimowej funkcji zastosowanej do przestrzeni nazw ⍵ :)⍵M
(⍵.Match
) tekst litery M¯1↓
upuść ostatni znak (symbol+
-
×
lub÷
)1↓
upuść pierwszy znak (symbol)⍎
wykonaj jako kod APL(
⍕
stringify)≡
(⍣≡
) powtarzaj zamianę, dopóki nie nastąpią żadne zmianyźródło
⍕
⎕R
nie może działać na danych liczbowych. Dzięki.Haskell , 132 znaki
(134 bajty, ponieważ
×
i÷
wziąć dwa bajty w UTF-8)Wypróbuj online!
f
analizuje jak najwięcej danych wejściowych i daje wynik, a także pozostały ciąg (który jest pusty w przypadkach testowych). Jeśli nie jest to zgodne z regułami, usuń nie dający się oddzielić ciąg resztHaskell , 139 znaków
źródło
Perl,
6453 bajtówUwzględnij
+1
dla-p
Przypadkowo implementuje także
,
(wyrzuca pierwszy argument), a czasem.
(dołącza argumenty razem)..
nie działa jednak niezawodnie, ponieważ koliduje z kropką dziesiętną zarówno na poziomie analizy, jak i na poziomie ocenyźródło
Java 8,
205200 bajtówPort odpowiedzi C # @Charlie .
-5 bajtów dzięki @ceilingcat .
Wypróbuj online.
źródło