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
Try it online!
Explanation
As H.PWiz figured out we can use Haskell's lexer here to break up the string into it's parts. (Earlier I was using span(>'/')
) And Laikoni pointed out that <$>
works just like mapSnd
from Data.Tuple
.
The pattern guard breaks up our code into the three numbers we want using lex
. lex
invokes haskell's lexer to break off the first token. It returns a list with each element representing a possible way to parse the string. These elements are tuples with the first element being the first token and the rest of the string being the second element. Now since the input format is very regular we are only ever going to have exactly one parse, so we can always take the first one. The first thing we do is invoke lex
on the input
lex x
Then we unwrap it from it's list giving us a 2-tuple
lex x!!0
The first token will be the whole part of the mixed fraction leaving the fraction prepended by a space to still parse. Then since tuples are Functors
we can use (<$>)
an alias for fmap
to apply lex
to the second element of the tuple.
lex<$>lex x!!0
This eats through the space and breaks off the next token, the numerator of our fraction. Now we bind this to a pattern match using <-
. Our pattern is
(a,(c,s:d):_)
a
grabs the whole part of the fraction, our first token. :_
unwraps the list resulting from our second lex
. c
grabs the second token we lexed, that is the numerator of the fraction. Everything that remains is bound to s:d
which splits it into its first character, guaranteed by the format to be a /
and the remainder which will be the denominator.
Now that we have parsed the input we do the actual computation:
show(r a*r d+r c)++s:d
Where r
is the read function we bound earlier.
It is important to note that lex
returns a list empty if it fails and non-empty if it succeeds. Why this is not a Maybe
I do not know.
x
,y
andz
be negative? \$\endgroup\$/
between, it's a newline)? \$\endgroup\$