Haskell , 74 67 63 byte
r=read
f x|(a,(c,s:d):_)<-lex<$>lex x!!0=show(r a*r d+r c)++s:d
Cobalah online!
Penjelasan
Seperti yang diketahui oleh H.PWiz , kita dapat menggunakan lexer Haskell di sini untuk memecah string menjadi bagian-bagiannya. (Sebelumnya saya menggunakan span(>'/')
) Dan Laikoni menunjukkan bahwa itu <$>
berfungsi seperti mapSnd
dari Data.Tuple
.
Pengawal pola memecah kode kami menjadi tiga angka yang ingin kita gunakan lex
. lex
memanggil haskell's lexer untuk memutus token pertama. Ini mengembalikan daftar dengan masing-masing elemen yang mewakili cara yang mungkin untuk mengurai string. Elemen-elemen ini adalah tupel dengan elemen pertama menjadi token pertama dan sisanya dari string menjadi elemen kedua. Sekarang karena format input sangat teratur, kami hanya akan memiliki satu parse, jadi kami selalu dapat mengambil yang pertama. Hal pertama yang kita lakukan adalah memanggil lex
input
lex x
Lalu kami membuka bungkusnya dari daftar itu memberi kami 2-tuple
lex x!!0
Token pertama akan menjadi seluruh bagian dari fraksi campuran yang meninggalkan fraksi yang didahului oleh spasi untuk tetap diuraikan. Kemudian karena tupel Functors
kita dapat menggunakan (<$>)
alias untuk fmap
menerapkan lex
ke elemen kedua tupel.
lex<$>lex x!!0
Ini memakan ruang dan memutuskan token berikutnya, pembilang dari fraksi kami. Sekarang kita ikat ini ke pencocokan pola menggunakan <-
. Pola kita adalah
(a,(c,s:d):_)
a
meraih seluruh bagian dari fraksi, token pertama kami. :_
membuka daftar yang dihasilkan dari yang kedua lex
. c
meraih token kedua yang kami lexed, yaitu pembilang dari pecahan. Segala sesuatu yang tersisa terikat pada s:d
yang membaginya menjadi karakter pertama, dijamin oleh format menjadi /
dan sisanya yang akan menjadi penyebutnya.
Sekarang kita telah mem-parsing input, kita melakukan perhitungan yang sebenarnya:
show(r a*r d+r c)++s:d
Di mana r
fungsi baca yang kita ikat sebelumnya.
Penting untuk dicatat bahwa lex
mengembalikan daftar kosong jika gagal dan tidak kosong jika berhasil. Kenapa ini bukan Maybe
saya tidak tahu.