{-# LANGUAGE LambdaCase #-} module Main where import Data.Functor import Data.Matrix hiding (trace) import Data.List import Debug.Trace import Data.Maybe parse :: String -> Matrix Char parse = fromLists . lines getGroup :: (Int,Int) -> Matrix Char -> [(Int,Int)] getGroup (i,j) s = let e = getElem i j s in go e [(i,j)] [] where go :: Char -> [(Int,Int)] -> [(Int,Int)] -> [(Int,Int)] go _ [] v = v go c (x@(i,j):xs) v | x `elem` v = go c xs v | uncurry safeGet x s /= Just c = go c xs v | otherwise = go c (filter (isJust . flip (uncurry safeGet) s) [(i+1,j),(i-1,j),(i,j+1),(i,j-1)] ++ xs) (x:v) groups :: Matrix Char -> [[(Int,Int)]] groups s = go [(i,j) | i <- [1 .. nrows s], j <- [1 .. ncols s]] [] where go :: [(Int,Int)] -> [[(Int,Int)]] -> [[(Int,Int)]] go [] v = v go (x:xs) v | any (x `elem`) v = go xs v | otherwise = go xs (nub (getGroup x s):v) perimeter :: [(Int,Int)] -> Int perimeter s = length $ s >>= \(i,j) -> [(i,j+1),(i,j-1),(i+1,j),(i-1,j)] \\ s solve1 :: Matrix Char -> Int solve1 s = let g = groups s; p = perimeter <$> g in sum $ zipWith (*) (length <$> g) p solve2 :: Matrix Char -> Int solve2 = undefined main :: IO () main = readFile "inputs/12" <&> parse >>= \i -> print (solve1 i) >> print (solve2 i)