aboutsummaryrefslogtreecommitdiff
path: root/execs/Day07.hs
blob: 72043afbdf88ad5da7e5473dec6b63c222471cbf (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
32
33
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