advent-of-code/2023/haskell/solutions/Day09.hs
2023-12-09 16:13:21 +01:00

41 lines
1,022 B
Haskell

{-# LANGUAGE OverloadedStrings #-}
module Day09 (parse, solveA, solveB) where
import Data.Void (Void)
import Data.Text (Text)
import Data.Bifunctor (first)
import Text.Megaparsec (Parsec, errorBundlePretty, runParser, sepBy, many, eof)
import Text.Megaparsec.Char (char, newline, space)
import Text.Megaparsec.Char.Lexer (signed, decimal)
type Parser = Parsec Void Text
parse :: Text -> Either String [[Int]]
parse = first errorBundlePretty . runParser nss ""
where
nss :: Parser [[Int]]
nss = many (signed space decimal `sepBy` char ' ' <* newline) <* eof
pairs :: [a] -> [(a, a)]
pairs [] = []
pairs xs = zip xs $ tail xs
diffs :: [Int] -> [[Int]]
diffs ns
| all (0 ==) ns = [ns]
| otherwise = ns : diffs (diff ns)
where
diff :: [Int] -> [Int]
diff = map (uncurry $ flip (-)) . pairs
solve :: ([Int] -> Int -> Int) -> [[Int]] -> Int
solve op = sum . map (foldr op 0 . diffs)
solveA :: [[Int]] -> Int
solveA = solve $ (+) . last
solveB :: [[Int]] -> Int
solveB = solve $ (-) . head