module Day9_1 where import System.IO (openFile, IOMode (ReadMode), hClose, hGetContents) import Data.Char (digitToInt) import Data.List (sort) -- i gave up on my original solution -- this isn't very original and is influcenced by other people's solutions -- i'm sorry columns :: String -> Int columns str = maximum $ map length $ lines str xy :: Int -> Int -> [[Int]] -> (Int, Int) -> Int xy w h arr (x, y) | x < 0 || x >= w = 9 | y < 0 || y >= h = 9 | otherwise = arr !! y !! x -- left, right, up, down from current coord neigh :: (Int, Int) -> [(Int, Int)] neigh (x, y) = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)] basin :: Int -> Int -> [[Int]] -> [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)] basin w h ints acc [] = acc basin w h ints acc (x:xs) | pos x == 9 || x `elem` acc = basin w h ints acc xs | otherwise = basin w h ints (x:acc) (xs ++ neigh x) where pos = xy w h ints main :: IO () main = do input <- openFile "inputs/9.txt" ReadMode contents <- hGetContents input let ints = map (map digitToInt) $ lines contents let width = columns contents let height = length ints let coordMap = [ (x, y) | x <- [0..width-1], y <- [0..height-1] ] let pos = xy width height ints let lowest = [ coord | coord <- coordMap, and [neighbor > pos coord | neighbor <- pos <$> neigh coord] ] print . product . take 3 . reverse . sort $ map (length . basin width height ints [] . pure) lowest hClose input