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
|
import Data.Char
import Data.List
import Control.Monad
import qualified Data.Map.Strict as Map
import Data.Map.Strict ((!))
realSue :: Map.Map String (Int -> Bool)
realSue = Map.fromList [ -- for part 1, make all functions equalities
("children", (==3)),
("cats", (>7)),
("samoyeds", (==2)),
("pomeranians",(<3)),
("akitas", (==0)),
("vizslas", (==0)),
("goldfish", (<5)),
("trees", (>3)),
("cars", (==2)),
("perfumes", (==1))]
parse :: String -> [(String,Int)]
parse s = parse' $ drop 2 $ words s
parse' :: [String] -> [(String,Int)]
parse' [] = []
parse' (k:v:xs) = (init k,read $ takeWhile isDigit v) : parse' xs
matches :: [(String,Int)] -> Map.Map String (Int -> Bool) -> Bool
matches [] _ = True
matches ((k,v):atts) map = (map ! k) v && matches atts map
day16 :: IO ()
day16 = do
input <- liftM (zip [1..] . map parse . lines) $ readFile "day16.txt"
sequence_ $ map (print . fst) $ filter (\(i,atts) -> matches atts realSue) input
main = day16
|