Haskell , 74 67 63 bytes
r=read
f x|(a,(c,s:d):_)<-lex<$>lex x!!0=show(r a*r d+r c)++s:d
Pruébalo en línea!
Explicación
Como H.PWiz descubrió, podemos usar el lexer de Haskell aquí para dividir la cuerda en sus partes. (Anteriormente estaba usando span(>'/')
) Y Laikoni señaló que <$>
funciona igual que mapSnd
desde Data.Tuple
.
El protector de patrón divide nuestro código en los tres números que queremos usar lex
. lex
invoca el lexer de Haskell para romper la primera ficha. Devuelve una lista con cada elemento que representa una forma posible de analizar la cadena. Estos elementos son tuplas con el primer elemento como el primer token y el resto de la cadena como el segundo elemento. Ahora, dado que el formato de entrada es muy regular, solo vamos a tener exactamente un análisis, por lo que siempre podemos tomar el primero. Lo primero que hacemos es invocar lex
en la entrada
lex x
Luego lo desenvolvemos de su lista dándonos una tupla de 2
lex x!!0
La primera ficha será la parte completa de la fracción mixta, dejando la fracción antepuesta por un espacio para analizar aún. Entonces, dado que las tuplas son Functors
, podemos usar (<$>)
un alias para fmap
aplicar lex
al segundo elemento de la tupla.
lex<$>lex x!!0
Esto come a través del espacio y rompe la siguiente ficha, el numerador de nuestra fracción. Ahora vinculamos esto a una coincidencia de patrón usando <-
. Nuestro patrón es
(a,(c,s:d):_)
a
agarra toda la parte de la fracción, nuestro primer token. :_
desenvuelve la lista resultante de nuestro segundo lex
. c
agarra la segunda ficha que lexedimos, que es el numerador de la fracción. Todo lo que queda está vinculado a lo s:d
que lo divide en su primer carácter, garantizado por el formato de ser un /
y el resto que será el denominador.
Ahora que hemos analizado la entrada, hacemos el cálculo real:
show(r a*r d+r c)++s:d
¿Dónde r
está la función de lectura que vinculamos anteriormente?
Es importante tener en cuenta que lex
devuelve una lista vacía si falla y no vacía si tiene éxito. Por qué esto no es un Maybe
no lo sé.