Haskell , 74 67 63 bayt
r=read
f x|(a,(c,s:d):_)<-lex<$>lex x!!0=show(r a*r d+r c)++s:d
Çevrimiçi deneyin!
açıklama
H.PWiz'in anladığı gibi , dizeyi parçalarına ayırmak için Haskell'in lexer'ını kullanabiliriz. (Daha önce ben kullanıyordum span(>'/')
) Ve Laikoni olduğuna dikkat çeken <$>
tıpkı eserleri mapSnd
arasından Data.Tuple
.
Desen koruması, kodumuzu kullanmak istediğimiz üç numaraya böler lex
. lex
ilk jetonu kırmak için haskell'in sözlüğünü çağırır. Her öğenin dizeyi ayrıştırmanın olası bir yolunu temsil eden bir liste döndürür. Bu elemanlar, ilk elemanın ilk belirteç ve geri kalan dizenin ikinci eleman olduğu tupllerdir. Şimdi giriş formatı çok düzenli olduğu için sadece bir tane ayrıştırma yapacağız, bu yüzden her zaman birincisini alabiliriz. Yaptığımız ilk şey lex
girdiye çağırmak
lex x
Sonra listeden paketini açıyoruz ve bize 2-demet veriyoruz
lex x!!0
İlk belirteç, karışık ayrışmanın tamamının bir kısmı olacaktır. Sonra tuples olduğu için tupleın ikinci elemanına uygulamak için bir takma ad Functors
kullanabiliriz .(<$>)
fmap
lex
lex<$>lex x!!0
Bu boşlukta yer alır ve bir sonraki jetonu kesirimizin payıdır. Şimdi bunu kullanarak bir kalıp eşleşmesine bağlarız <-
. Bizim modelimiz
(a,(c,s:d):_)
a
ilk simgemiz olan kesirin tamamını kapar. :_
bizim ikinci sonuç listesinden açar lex
. c
ikinci kez belirlediğimiz jetonu, yani kesirin payıdır. Geri kalan her şey, s:d
onu ilk karakterine ayıran, a'nın formatı /
ve payda olacak geri kalanı ile garanti edilir .
Şimdi girdiyi ayrıştırdığımız için gerçek hesaplamayı yapıyoruz:
show(r a*r d+r c)++s:d
r
Daha önce bağladığımız okuma fonksiyonu nerede .
lex
Bir listenin başarısız olması durumunda boş, başarılı olması durumunda boş olmadığını döndürmesi önemlidir . Neden bu bir Maybe
bilmiyorum.