# Advent of Code - 2021 - 9 ## Haskell ```hs import Data.List (sort) parseInput :: String -> [[Int]] parseInput = map (map (\x -> read [x])) . lines rowLength = length . head colLength = length point m (x, y) = if 0 <= y && y < colLength m && 0 <= x && x < rowLength m then m !! y !! x else 9 neighbours (x, y) = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)] isLocalMin :: (Int, Int) -> [[Int]] -> Bool isLocalMin p@(x, y) m = all (> point m p) $ map (point m) $ neighbours p localMinima :: (Int, Int) -> [[Int]] -> [(Int, Int)] localMinima p@(x, y) m = if x < rowLength m then if isLocalMin p m then p : localMinima (x + 1, y) m else localMinima (x + 1, y) m else if y < colLength m then localMinima (0, y + 1) m else [] riskLevel m p = 1 + point m p part1 m = sum $ map (riskLevel m) $ localMinima (0, 0) m contains p l = any (== p) l collectBasin m s p@(x, y) = if point m p < 9 && not (contains p s) then foldl (collectBasin m) (p:s) (neighbours p) else s collectBasins m = map (collectBasin m []) part2 m = let f = product . take 3 . reverse . sort . map (sum . map length) in f $ collectBasins m $ localMinima (0, 0) m main = fmap parseInput (readFile "input.txt") >>= \x -> print (part1 x, part2 x) ```