Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
2024-12-05 13:53:34 +05:30
parent ca69182e55
commit 22acd853d8
2 changed files with 62 additions and 2 deletions

View File

@@ -8,7 +8,10 @@ build-type: Simple
common common
ghc-options: -Wall -O3
default-extensions: LambdaCase
default-extensions:
LambdaCase
ViewPatterns
build-depends:
, base >=4.14 && <5
, parsec >=3
@@ -17,7 +20,6 @@ library libaoc
import: common
exposed: False
hs-source-dirs: lib
build-depends: containers
exposed-modules: AoC
executable day1
@@ -49,3 +51,11 @@ executable day4alt
hs-source-dirs: src
main-is: Day4Alt.hs
build-depends: libaoc
executable day5
import: common
hs-source-dirs: src
main-is: Day5.hs
build-depends:
, containers
, libaoc

50
src/Day5.hs Normal file
View File

@@ -0,0 +1,50 @@
module Main where
import qualified AoC as A (extract)
import Data.Bool (bool)
import Data.List (sortBy, tails)
import qualified Data.Set as S
import Text.Parsec (char, digit, many1, newline, parse, sepBy1, sepEndBy1)
import Text.Parsec.String (Parser)
type Rule = (Int, Int)
type Rules = S.Set Rule
type Update = [Int]
parseRules :: Parser (Rules, [Update])
parseRules = do
rules <- S.fromList <$> parseRule `sepEndBy1` newline
newline
updates <- parseUpdate `sepEndBy1` newline
return (rules, updates)
where
parseRule :: Parser Rule
parseRule = (,) <$> (read <$> many1 digit <* char '|') <*> (read <$> many1 digit)
parseUpdate :: Parser Update
parseUpdate = (read <$> many1 digit) `sepBy1` char ','
middle :: [a] -> a
middle xs = xs !! (length xs `div` 2)
isOrdered :: Rules -> Update -> Bool
isOrdered rules (first : rest) = all (flip S.member rules . (,) first) rest
isOrdered _ _ = False
part1 :: Rules -> [Update] -> Int
part1 rules = sum . map middle . filter (all (isOrdered rules) . init . tails)
part2 :: Rules -> [Update] -> Int
part2 rules =
sum
. map (middle . sortBy (\x -> bool GT LT . flip S.member rules . (,) x))
. filter (not . all (isOrdered rules) . init . tails)
main :: IO ()
main =
do
raw <- readFile "./inputs/day5.in"
let (rules, updates) = A.extract $ parse parseRules "" raw
putStr "Part 1: " >> print (part1 rules updates)
putStr "Part 2: " >> print (part2 rules updates)