Simplified day 9
[advent-of-code-23.git] / advent09 / Main.hs
1 -- Writeup at https://work.njae.me.uk/2023/12/09/advent-of-code-2023-day-09/
2
3 import AoC
4 import Data.List
5 import Prelude hiding (seq)
6
7 type Sequence = [[Int]]
8
9 main :: IO ()
10 main =
11 do dataFileName <- getDataFileName
12 text <- readFile dataFileName
13 let histories = readInput text
14 -- print histories
15 let seqs = fmap expand histories
16 -- print seqs
17 -- let seqs' = fmap extend seqs
18 -- print seqs'
19 print $ part1 seqs
20 let rseqs = fmap (expand . reverse) histories
21 print $ part1 rseqs
22
23 part1 :: [Sequence] -> Int
24 part1 = sum . fmap (evaluate . extend)
25
26
27 readInput :: String -> [[Int]]
28 readInput = fmap (fmap read . words) . lines
29
30 expand :: [Int] -> Sequence
31 expand seq = unfoldr go seq
32 where go xs
33 | all (== 0) xs = Nothing
34 | otherwise = Just (xs, differences xs)
35
36 differences :: [Int] -> [Int]
37 differences xs = zipWith (-) (tail xs) xs
38
39 extend :: Sequence -> Sequence
40 extend = fst . foldr extendRow ([], 0)
41
42 extendRow :: [Int] -> ([[Int]], Int) -> ([[Int]], Int)
43 extendRow row (seq, n) = ((row ++ [n']) : seq, n')
44 where n' = last row + n
45
46 evaluate :: Sequence -> Int
47 evaluate = last . head