module Main where import Data.Map (Map) import qualified Data.Map as Map import Utils myBag = "shiny gold" parseContained :: [String] -> [(Int, String)] parseContained [] = [] parseContained (count:b:c:_:rest) = (read count, unwords [b,c]):parseContained rest parseLine :: [String] -> (String, [(Int, String)]) parseLine s = (leadingBag, contained) where leadingBag = unwords $ take 2 s trailingBags = drop 4 s contained = case head trailingBags of "no" -> [] _ -> parseContained trailingBags 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