Done day 13
[advent-of-code-23.git] / advent09 / MainComplicated.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
6 newtype Sequence = Sequence [[Int]] deriving (Show, Eq)
7
8 main :: IO ()
9 main =
10 do dataFileName <- getDataFileName
11 text <- readFile dataFileName
12 let histories = readInput text
13 -- print histories
14 let seqs = fmap (expand . Sequence . pure) histories
15 -- print seqs
16 -- let seqs' = fmap extend seqs
17 -- print seqs'
18 print $ part1 seqs
19 let rseqs = fmap (expand . Sequence . pure . reverse) histories
20 print $ part1 rseqs
21
22 part1 :: [Sequence] -> Int
23 part1 = sum . fmap (evaluate . extend)
24
25
26 readInput :: String -> [[Int]]
27 readInput = fmap (fmap read . words) . lines
28
29 expand :: Sequence -> Sequence
30 expand (Sequence xss)
31 | all (== 0) $ last xss = Sequence xss
32 | otherwise = expand $ Sequence $ xss ++ [differences $ last xss]
33
34 differences :: [Int] -> [Int]
35 differences xs = zipWith (-) (tail xs) xs
36
37 extend :: Sequence -> Sequence
38 extend (Sequence xss) = Sequence $ fst $ foldr extendRow ([], 0) xss
39
40 extendRow :: [Int] -> ([[Int]], Int) -> ([[Int]], Int)
41 extendRow row (seq, n) = ((row ++ [n']) : seq, n')
42 where n' = last row + n
43
44 evaluate :: Sequence -> Int
45 evaluate (Sequence xss) = last $ head xss