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 module Main where
import System.Environment (getArgs) import System.Environment (getArgs)
import System.IO (Handle, hIsEOF, hGetLine, withFile, IOMode(ReadMode))
import Text.Read (readMaybe)
import Data.List (sort) import Data.List (sort)
import Data.Char (isDigit, isSpace)
mapSnd :: (b -> c) -> (a, b) -> (a, c) import Text.Parsec (parse, many, char, endBy)
mapSnd f (a, b) = (a, f b) import Text.ParserCombinators.Parsec (GenParser)
import Text.ParserCombinators.Parsec.Number (decimal)
parseLine :: String -> IO (Int, Int) line :: GenParser Char st (Int, Int)
parseLine line = let (l, (_, r)) = (mapSnd (span isSpace). span isDigit) line line = decimal >>= \l -> many (char ' ') >> decimal >>= \r -> return (l, r)
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]) locationIDs :: GenParser Char st [(Int, Int)]
readLists h = do locationIDs = endBy line (char '\n')
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 :: [Int] -> [Int] -> Int
computeDistance l r = sum (zipWith (curry (abs . uncurry (-))) l r) computeDistance l r = sum (zipWith (curry (abs . uncurry (-))) l r)
@ -36,6 +21,9 @@ main :: IO ()
main = do main = do
args <- getArgs args <- getArgs
(fp:_) <- return args (fp:_) <- return args
(l, r) <- withFile fp ReadMode readLists content <- readFile fp
case parse locationIDs fp content of
putStrLn ("Solution (Part 1) : " ++ show (computeDistance (sort l) (sort r))) 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 executable day1
import: warnings import: warnings
main-is: Main.hs 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 hs-source-dirs: day1
default-language: Haskell2010 default-language: Haskell2010