[hs] Clean up 2020_07
This commit is contained in:
parent
fe41f42ccc
commit
a97a5be6c8
2 changed files with 24 additions and 22 deletions
|
|
@ -7,6 +7,7 @@ dependencies:
|
||||||
- megaparsec
|
- megaparsec
|
||||||
- optparse-applicative
|
- optparse-applicative
|
||||||
- text
|
- text
|
||||||
|
- transformers
|
||||||
|
|
||||||
library:
|
library:
|
||||||
source-dirs: src
|
source-dirs: src
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue