aoc-2024-haskell/day5/Main.hs

45 lines
1.4 KiB
Haskell
Raw Normal View History

2024-12-10 00:09:53 +01:00
module Main where
import System.Environment (getArgs)
import Data.Maybe (mapMaybe)
import Text.Parsec (parse, Parsec, endBy, sepBy1, char, newline, many)
import Text.ParserCombinators.Parsec.Number (decimal)
type PageOrdering = (Int, Int)
type PagesUpdate = [Int]
printInfo :: Parsec String () ([PageOrdering], [PagesUpdate])
printInfo = (,) <$> orderings <*> (newline *> pagesUpdates) <* many (char '\n')
where
pagesUpdates :: Parsec String () [PagesUpdate]
pagesUpdates = endBy (sepBy1 decimal $ char ',') newline
orderings :: Parsec String () [PageOrdering]
orderings = endBy ((,) <$> decimal <*> (char '|' *> decimal)) $ char '\n'
allDependencies :: [a] -> [(a, a)]
allDependencies (h:tl) = map (flip (,) h) tl ++ allDependencies tl
allDependencies [] = []
middleElement :: [a] -> Maybe a
middleElement [] = Nothing
middleElement [a] = Just a
middleElement (_:h':tl) = case reverse (h':tl) of
(_:middle) -> middleElement middle
[] -> Nothing
part1 :: FilePath -> IO Int
part1 fp = do
content <- readFile fp
(requiredOrderings, pagesUpdates) <- either (fail . show) return $ parse printInfo fp content
let wellOrdered = filter (all (`notElem` requiredOrderings) . allDependencies) pagesUpdates
return $ sum $ mapMaybe middleElement wellOrdered
main :: IO ()
main = do
args <- getArgs
(fp:_) <- return args
resPart1 <- part1 fp
putStrLn $ "Solution (Part 1) : " ++ show resPart1