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
|
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)))
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue