feat(day1): Use parsec instead of parsing by hand
This commit is contained in:
parent
022cf2a609
commit
05f4bc61cb
38
day1/Main.hs
38
day1/Main.hs
|
@ -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)))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue