import AoC import Control.Monad import Data.List import Data.Maybe slidingWindow :: Int -> [a] -> [[a]] slidingWindow n xs | length xs < n = [] | otherwise = take n xs : slidingWindow n (tail xs) summingTo :: (Eq a, Num a) => Int -> a -> [a] -> Maybe [a] n `summingTo` x = find ((==x) . sum) . replicateM n sublistSummingTo :: (Num a, Ord a) => a -> [a] -> Maybe [a] sublistSummingTo n = fmap snd . find ((== n) . fst) . scanl go (0, []) where go = dropNeeded .: addToAcc addToAcc (sum, parts) x = (sum+x, parts++[x]) dropNeeded = fromJust . find ((<= n) . fst) . iterate dropPart dropPart (sum, (x:xs)) = (sum-x, xs) part1 :: [Int] -> Int part1 = snd . fromJust . find (not . uncurry doesSum) . map (\xs -> (init xs, last xs)) . slidingWindow 26 where doesSum xs y = isJust $ 2 `summingTo` y $ xs part2 :: [Int] -> Int part2 xs = minimum range + maximum range where range = fromJust $ sublistSummingTo (part1 xs) xs main = runAoC (map read . lines) part1 part2