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 mapSndarasından Data.Tuple.
Desen koruması, kodumuzu kullanmak istediğimiz üç numaraya böler lex. lexilk 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 lexgirdiye ç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 Functorskullanabiliriz .(<$>)fmaplex
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):_)
ailk simgemiz olan kesirin tamamını kapar. :_bizim ikinci sonuç listesinden açar lex. cikinci kez belirlediğimiz jetonu, yani kesirin payıdır. Geri kalan her şey, s:donu 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
rDaha önce bağladığımız okuma fonksiyonu nerede .
lexBir listenin başarısız olması durumunda boş, başarılı olması durumunda boş olmadığını döndürmesi önemlidir . Neden bu bir Maybebilmiyorum.