blob: a0c1eb0f8b48bee68e35e4869f561fe5cf18f829 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
module Main where
import Data.Map (Map)
import qualified Data.Map as Map
import Utils
myBag = "shiny gold"
parseContained :: [String] -> [(Int, String)]
parseContained [] = []
parseContained ("no":_) = []
parseContained (count:b:c:_:rest) = (read count, unwords [b,c]):parseContained rest
parseLine :: [String] -> (String, [(Int, String)])
parseLine s = (leadingBag, parseContained trailingBags)
where leadingBag = unwords (take 2 s)
trailingBags = drop 4 s
canContain :: Map String [(Int, String)] -> String -> Bool
canContain m outer = myBag `elem` inners || any (canContain m) inners
where inners = map snd $ m Map.! outer
countNested :: String -> Map String [(Int, String)] -> Int
countNested s m = foldl (\acc (c,b) -> acc + c * (1 + countNested b m)) 0 $ m Map.! s
main :: IO ()
main = do
n <- map (parseLine . words) . lines <$> readFile "input/07"
let q = Map.fromList n
print $ howMany (canContain q . fst) $ Map.toList q
print $ countNested myBag q
|