Haskell , 74 67 63 bajtów
r=read
f x|(a,(c,s:d):_)<-lex<$>lex x!!0=show(r a*r d+r c)++s:d
Wypróbuj online!
Wyjaśnienie
Jak się zorientował H.PWiz , możemy tutaj użyć leksyk Haskella, aby rozbić sznurek na części. (Wcześniej korzystałem span(>'/')) I Laikoni wskazał, że <$>działa tak samomapSnd od Data.Tuple.
Strażnik wzorów dzieli nasz kod na trzy liczby, których chcemy użyć lex. lexprzywołuje leksykon haskell, aby zerwać pierwszy token. Zwraca listę z każdym elementem reprezentującym możliwy sposób parsowania łańcucha. Te elementy są krotkami, przy czym pierwszy element jest pierwszym tokenem, a reszta ciągu jest drugim elementem. Ponieważ format wejściowy jest bardzo regularny, zawsze będziemy mieli tylko jedną analizę, więc zawsze możemy wziąć pierwszą. Pierwszą rzeczą, którą robimy, jest wywołanie lexna wejściu
lex x
Następnie odwijamy go z listy, dając nam 2-krotkę
lex x!!0
Pierwszy token będzie całą częścią mieszanej frakcji, pozostawiając frakcję poprzedzoną spacją, aby nadal analizować. Ponieważ krotki są Functors, możemy użyć (<$>)aliasu, fmapaby zastosować lexdo drugiego elementu krotki.
lex<$>lex x!!0
To zjada przestrzeń i odrywa następny token, licznik naszej frakcji. Teraz łączymy to z dopasowaniem wzorca za pomocą <-. Nasz wzór to
(a,(c,s:d):_)
achwyta całą część frakcji, naszego pierwszego tokena. :_rozpakowuje listę wynikającą z naszego drugiego lex. cchwyta drugi żeton, który sprawdziliśmy, czyli licznik ułamka. Wszystko, co pozostaje, jest z tym związanes:d co dzieli go na pierwszy znak, co gwarantuje format to/ a reszta, która będzie mianownikiem.
Po przeanalizowaniu danych wejściowych wykonujemy obliczenia:
show(r a*r d+r c)++s:d
Gdzie r jest funkcja odczytu, którą związaliśmy wcześniej.
Należy zauważyć, że lexzwraca listę pustą, jeśli się nie powiedzie, i niepustą, jeśli się powiedzie. Dlaczego to nie jest Maybenie wiem.