[hs] Clean up 2020_07

This commit is contained in:
Joscha 2020-12-07 10:00:14 +00:00
parent fe41f42ccc
commit a97a5be6c8
2 changed files with 24 additions and 22 deletions

View file

@ -7,6 +7,7 @@ dependencies:
- megaparsec - megaparsec
- optparse-applicative - optparse-applicative
- text - text
- transformers
library: library:
source-dirs: src source-dirs: src

View file

@ -7,6 +7,7 @@ module Aoc.Y2020.D07
import Control.Monad import Control.Monad
import Data.Maybe import Data.Maybe
import Control.Monad.Trans.State
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Text as T import qualified Data.Text as T
@ -25,19 +26,12 @@ type BagMap = Map.Map BagName [BagCount]
pBagName :: Parser T.Text pBagName :: Parser T.Text
pBagName = do pBagName = do
first <- word name <- mconcat <$> sequenceA [word, string " ", word]
void $ char ' ' void $ string " bags" <|> string " bag"
second <- word pure name
void $ char ' '
void $ string "bags" <|> string "bag"
pure $ first <> " " <> second
pBagCount :: Parser BagCount pBagCount :: Parser BagCount
pBagCount = do pBagCount = flip BagCount <$> (decimal <* char ' ') <*> pBagName
n <- decimal
void $ char ' '
name <- pBagName
pure $ BagCount name n
parser :: Parser BagMap parser :: Parser BagMap
parser = fmap Map.fromList $ manyLines $ do parser = fmap Map.fromList $ manyLines $ do
@ -47,10 +41,16 @@ parser = fmap Map.fromList $ manyLines $ do
void $ char '.' void $ char '.'
pure (name, bags) pure (name, bags)
children :: BagMap -> BagName -> Set.Set BagName children :: BagMap -> BagName -> State (Map.Map BagName (Set.Set BagName)) (Set.Set BagName)
children m b = children m b = do
sm <- get
case sm Map.!? b of
Just result -> pure result
Nothing -> do
let ch = map bcName $ fromMaybe [] $ m Map.!? b let ch = map bcName $ fromMaybe [] $ m Map.!? b
in foldr Set.union (Set.fromList ch) $ map (children m) ch result <- Set.unions . (Set.fromList ch :) <$> traverse (children m) ch
put $ Map.insert b result sm
pure result
countChildren :: BagMap -> BagName -> Int countChildren :: BagMap -> BagName -> Int
countChildren m b = countChildren m b =
@ -63,7 +63,8 @@ myBag = "shiny gold"
solver :: BagMap -> IO () solver :: BagMap -> IO ()
solver bags = do solver bags = do
putStrLn ">> Part 1" putStrLn ">> Part 1"
print $ length $ filter (Set.member myBag) $ map (children bags) $ Set.toList $ Map.keysSet bags let childrenPerBag = flip evalState Map.empty $ traverse (children bags) $ Map.keys bags
print $ length $ filter (Set.member myBag) childrenPerBag
putStrLn "" putStrLn ""
putStrLn ">> Part 2" putStrLn ">> Part 2"