quick and dirty
[aoc20.git] / 7 / one.icl
1 module one
2
3 import StdEnv
4 import Data.Func
5 import qualified Data.Map
6 from Data.Map import :: Map(..), fromList, get, find, keys, foldrWithKey, findWithDefault
7 import Text
8
9 read :: *File -> [Char]
10 read f
11 # (ok, l, f) = freadc f
12 | not ok = []
13 = [l:read f]
14
15 Start w
16 # (io, w) = stdio w
17 # bag = fromList (makeBag (read io))
18 = (one ['shiny gold'] bag, two bag ['shiny gold']-1)
19
20 one color bag = length $ filter id $ map (canContain bag color) $ filter ((<>)color) $ keys bag
21 two bag color = 1+sum[n*two bag c\\(n, c)<-findWithDefault [] color bag]
22
23 makeBag :: [Char] -> [([Char], [(Int, [Char])])]
24 makeBag ls = [(b, mkItem c)\\[b,c]<-map (split [' contain ']) $ split ['.\n'] ls]
25 where
26 mkItem :: [Char] -> [(Int, [Char])]
27 mkItem s = [(toInt (toString x), join [' '] xs)\\[x:xs]<-map (split [' ']) (split [', '] s)]
28
29 canContain bag color name = or [name == color:[canContain bag color child\\(n, child)<-findWithDefault [] name bag]]