30 lines
1,015 B
Haskell
30 lines
1,015 B
Haskell
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
|