module Main where import System.Environment (getArgs) import System.IO (Handle, hIsEOF, hGetLine, withFile, IOMode(ReadMode)) import Text.Read (readMaybe) import Data.List (sort) import Data.Char (isDigit, isSpace) mapSnd :: (b -> c) -> (a, b) -> (a, c) mapSnd f (a, b) = (a, f b) parseLine :: String -> IO (Int, Int) parseLine line = let (l, (_, r)) = (mapSnd (span isSpace). span isDigit) line in case readMaybe l >>= \l' -> readMaybe r >>= \r' -> return (l', r') of Just a -> return a Nothing -> fail "Input file is incorrectly formatted" readLists :: Handle -> IO ([Int], [Int]) readLists h = do shouldStop <- hIsEOF h if shouldStop then return ([], []) else do line <- hGetLine h (l, r) <- parseLine line (ls, rs) <- readLists h return (l:ls, r:rs) computeDistance :: [Int] -> [Int] -> Int computeDistance l r = sum (zipWith (curry (abs . uncurry (-))) l r) main :: IO () main = do args <- getArgs (fp:_) <- return args (l, r) <- withFile fp ReadMode readLists putStrLn ("Solution (Part 1) : " ++ show (computeDistance (sort l) (sort r)))