advent-of-code/2015/day16/day16.hs

48 lines
1.3 KiB
Haskell
Raw Normal View History

2024-12-03 14:29:15 +11:00
import Aoc
import Data.List.Split ( splitOn )
import Data.Char ( isDigit )
import Control.Arrow ( second )
import Data.Maybe ( fromMaybe )
parseLine :: String -> (Int, [(String, Int)])
parseLine line =
let ("Sue ", rest0) = splitAt 4 line in
let (n, rest1) = span isDigit rest0 in
let (':':' ':rest2) = rest1 in
let items = splitOn ", " rest2 in
(read n, map (second read . pair . splitOn ": ") items)
tape :: [(String, Int)]
tape = [
("children", 3),
("cats", 7),
("samoyeds", 2),
("pomeranians", 3),
("akitas", 0),
("vizslas", 0),
("goldfish", 5),
("trees", 3),
("cars", 2),
("perfumes", 1)
]
part1' :: (String -> Int -> Int -> Bool) -> [(Int, [(String, Int)])] -> Int
part1' predicate = fst . single . filter matches
where matches (_, items) = all itemMatches tape
where itemMatches (name, n) = case lookup name items of
Nothing -> True
Just n' -> predicate name n' n
part1 :: [(Int, [(String, Int)])] -> Int
part1 = part1' $ const (==)
part2 :: [(Int, [(String, Int)])] -> Int
part2 = part1' $ fromMaybe (==) . flip lookup [
("cats", (>)),
("trees", (>)),
("pomeranians", (<)),
("goldfish", (<))
]
main :: IO ()
main = aocMain (map parseLine) part1 part2