feat(day1): Use parsec instead of parsing by hand

This commit is contained in:
kale 2024-12-03 15:02:07 +01:00
parent 022cf2a609
commit 05f4bc61cb
Signed by: kalmenn
GPG key ID: F500055C44BC3834
2 changed files with 17 additions and 26 deletions

View file

@ -1,33 +1,18 @@
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)
import Text.Parsec (parse, many, char, endBy)
import Text.ParserCombinators.Parsec (GenParser)
import Text.ParserCombinators.Parsec.Number (decimal)
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"
line :: GenParser Char st (Int, Int)
line = decimal >>= \l -> many (char ' ') >> decimal >>= \r -> return (l, r)
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)
locationIDs :: GenParser Char st [(Int, Int)]
locationIDs = endBy line (char '\n')
computeDistance :: [Int] -> [Int] -> Int
computeDistance l r = sum (zipWith (curry (abs . uncurry (-))) l r)
@ -36,6 +21,9 @@ 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)))
content <- readFile fp
case parse locationIDs fp content of
Left e -> putStrLn ("Input file is incorrectly formatted : " ++ show e)
Right ids -> let (l, r) = unzip ids
in putStrLn ("Solution (Part 1) : "
++ show (computeDistance (sort l) (sort r)))

View file

@ -15,6 +15,9 @@ common warnings
executable day1
import: warnings
main-is: Main.hs
build-depends: base ^>=4.18.2.1
build-depends:
base ^>=4.18.2.1,
parsec ^>= 3.1.17.0,
parsec-numbers ^>= 0.1.0
hs-source-dirs: day1
default-language: Haskell2010