In today’s Programming Praxis exercise, our goal is to calculate and show the gas mileage given an input file containing the total amount of miles and the amount of fuel bought at each fuel stop. Let’s get started, shall we?
import Text.Printf import Text.XFormat.Read
Normally I’d use Parsec for something like this (and indeed in my first attempt), but the fact that parsing numbers requires token parsers makes the program less elegant. Instead, I used the XFormat package, which in this case produces cleaner code.
line :: String -> (Float, Float) line s = (m,g) where Just (m,_,g) = readf (Float, Space, Float) s
Once we’ve read in the number, calculating the mileage is a simple matter of taking the difference between each pair of mile totals and dividing it by the fuel amount. We use printf to format everything.
showLog :: [(Float, Float)] -> [String] showLog es = "Miles Gals Avg" : "------ ---- ----" : zipWith (\(m2,g) (m1,_) -> printf "%.0f %.1f %.1f" m2 g ((m2 - m1) / g)) (tail es) es
All that’s left to do is route the input through the functions above and output the result.
main :: IO () main = mapM_ putStrLn . showLog . map line . lines =<< readFile "input.txt"