blob: 1587e2be200897343c18bb404921dd6fdbfd7c2b (
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
34
35
36
|
module Main where
import Data.Map (Map)
import qualified Data.Map as Map
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 (Just inners) = map snd <$> Map.lookup outer m
countNested :: String -> Map String [(Int, String)] -> Int
countNested s m = if null l
then 0
else sum $ map counter l
where (Just l) = Map.lookup s m
counter (count, bag) = count + count * countNested bag m
main :: IO ()
main = do
n <- map (parseLine . words) . lines <$> readFile "input/07"
let q = Map.fromList n
print $ length $ filter (== True) $ map (canContain q . fst) $ Map.toList q
print $ countNested myBag q
|