aboutsummaryrefslogtreecommitdiff
path: root/execs/Day07.hs
diff options
context:
space:
mode:
Diffstat (limited to 'execs/Day07.hs')
-rw-r--r--execs/Day07.hs36
1 files changed, 36 insertions, 0 deletions
diff --git a/execs/Day07.hs b/execs/Day07.hs
new file mode 100644
index 0000000..1587e2b
--- /dev/null
+++ b/execs/Day07.hs
@@ -0,0 +1,36 @@
1module Main where
2
3import Data.Map (Map)
4import qualified Data.Map as Map
5
6myBag = "shiny gold"
7
8parseContained :: [String] -> [(Int, String)]
9parseContained [] = []
10parseContained (count:b:c:_:rest) = (read count, unwords [b,c]):parseContained rest
11
12parseLine :: [String] -> (String, [(Int, String)])
13parseLine s = (leadingBag, contained)
14 where leadingBag = unwords $ take 2 s
15 trailingBags = drop 4 s
16 contained = case head trailingBags of
17 "no" -> []
18 _ -> parseContained trailingBags
19
20canContain :: Map String [(Int, String)] -> String -> Bool
21canContain m outer = myBag `elem` inners || any (canContain m) inners
22 where (Just inners) = map snd <$> Map.lookup outer m
23
24countNested :: String -> Map String [(Int, String)] -> Int
25countNested s m = if null l
26 then 0
27 else sum $ map counter l
28 where (Just l) = Map.lookup s m
29 counter (count, bag) = count + count * countNested bag m
30
31main :: IO ()
32main = do
33 n <- map (parseLine . words) . lines <$> readFile "input/07"
34 let q = Map.fromList n
35 print $ length $ filter (== True) $ map (canContain q . fst) $ Map.toList q
36 print $ countNested myBag q