{-# Language QuasiQuotes #-}
{-# OPTIONS_GHC -Wno-x-partial #-}
{-|
Module      : Main
Description : Day 9 solution
Copyright   : (c) Eric Mertens, 2023
License     : ISC
Maintainer  : emertens@gmail.com

<https://adventofcode.com/2023/day/9>

Extend an 

>>> :{
:main +
"0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45
"
:}
114
2

-}
module Main where

import Advent (format)

-- | Parse the input and print out answers to both parts.
--
-- >>> :main
-- 1762065988
-- 1066
main :: IO ()
IO ()
main =
 do [[Int]]
input <- [format|2023 9 (%d& %n)*|]
    Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (([Int] -> Int) -> [[Int]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [Int] -> Int
nextInSequence [[Int]]
input))
    Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (([Int] -> Int) -> [[Int]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map ([Int] -> Int
nextInSequence ([Int] -> Int) -> ([Int] -> [Int]) -> [Int] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [Int]
forall a. [a] -> [a]
reverse) [[Int]]
input))

nextInSequence :: [Int] -> Int
nextInSequence :: [Int] -> Int
nextInSequence = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> ([Int] -> [Int]) -> [Int] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Int] -> Int) -> [[Int]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [Int] -> Int
forall a. HasCallStack => [a] -> a
last ([[Int]] -> [Int]) -> ([Int] -> [[Int]]) -> [Int] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Int] -> Bool) -> [[Int]] -> [[Int]]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile ((Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Int
0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=)) ([[Int]] -> [[Int]]) -> ([Int] -> [[Int]]) -> [Int] -> [[Int]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Int] -> [Int]) -> [Int] -> [[Int]]
forall a. (a -> a) -> a -> [a]
iterate [Int] -> [Int]
differences

differences :: [Int] -> [Int]
differences :: [Int] -> [Int]
differences [Int]
xs = (Int -> Int -> Int) -> [Int] -> [Int] -> [Int]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Int -> Int
forall a. Num a => a -> a -> a
subtract [Int]
xs ([Int] -> [Int]
forall a. HasCallStack => [a] -> [a]
tail [Int]
xs)