Haskell , 74 67 63 octets
r=read
f x|(a,(c,s:d):_)<-lex<$>lex x!!0=show(r a*r d+r c)++s:d
Essayez-le en ligne!
Explication
Comme H.PWiz l'a compris, nous pouvons utiliser le lexer de Haskell ici pour diviser la chaîne en ses parties. ( Un peu plus tôt , j'utilisais span(>'/')
) Et Laikoni fait remarquer que <$>
fonctionne comme mapSnd
de Data.Tuple
.
Le modèle de garde décompose notre code en trois chiffres que nous voulons utiliser lex
. lex
invoque le lexer de haskell pour rompre le premier jeton. Il renvoie une liste avec chaque élément représentant une manière possible d'analyser la chaîne. Ces éléments sont des tuples, le premier élément étant le premier jeton et le reste de la chaîne étant le deuxième élément. Maintenant, comme le format d'entrée est très régulier, nous n'aurons jamais qu'une seule analyse, nous pouvons donc toujours prendre la première. La première chose que nous faisons est d'invoquer lex
l'entrée
lex x
Ensuite, nous le déballons de sa liste en nous donnant un tuple 2
lex x!!0
Le premier jeton sera la partie entière de la fraction mixte, laissant la fraction ajoutée par un espace à analyser. Puis, puisque les tuples sont, Functors
nous pouvons utiliser (<$>)
un alias pour fmap
appliquer lex
au deuxième élément du tuple.
lex<$>lex x!!0
Cela dévore l'espace et rompt le jeton suivant, le numérateur de notre fraction. Maintenant, nous lions ceci à une correspondance de modèle en utilisant <-
. Notre modèle est
(a,(c,s:d):_)
a
saisit toute la partie de la fraction, notre premier jeton. :_
déballe la liste issue de notre deuxième lex
. c
saisit le deuxième jeton que nous avons lexé, à savoir le numérateur de la fraction. Tout ce qui reste est lié à s:d
ce qui le divise en son premier caractère, garanti par le format comme un /
et le reste qui sera le dénominateur.
Maintenant que nous avons analysé l'entrée, nous effectuons le calcul réel:
show(r a*r d+r c)++s:d
Où r
est la fonction de lecture que nous avons liée plus tôt.
Il est important de noter que lex
retourne une liste vide si elle échoue et non vide si elle réussit. Pourquoi ce n'est pas un Maybe
je ne sais pas.