aboutsummaryrefslogtreecommitdiff
path: root/execs/Day07.hs
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