diff --git a/hs/src/Aoc/Y2020/D09.hs b/hs/src/Aoc/Y2020/D09.hs index 66685ff..f9e9e9c 100644 --- a/hs/src/Aoc/Y2020/D09.hs +++ b/hs/src/Aoc/Y2020/D09.hs @@ -1,15 +1,8 @@ -{-# LANGUAGE RecordWildCards #-} - module Aoc.Y2020.D09 ( day ) where -import Control.Monad -import Data.Foldable import Data.List -import Data.Maybe - -import qualified Data.Sequence as Seq import Aoc.Day import Aoc.Parse @@ -18,32 +11,18 @@ parser :: Parser [Int] parser = manyLines decimal splitAndGroup :: Int -> [Int] -> [([Int], Int)] -splitAndGroup width - = map (\l -> (take width l, l !! width)) - . filter ((> width) . length) - . tails +splitAndGroup width xs = case splitAt width xs of + (_, []) -> [] + (as, b:_) -> (as, b) : splitAndGroup width (drop 1 xs) isValid :: [Int] -> Int -> Bool -isValid nums n = not $ null $ do - a <- nums - b <- nums - guard $ a /= b - guard $ a + b == n - pure () +isValid nums n = elem n $ (+) <$> nums <*> nums --- Only works if all numbers are positive. -findRange :: Int -> [Int] -> Maybe [Int] -findRange target = helper 0 Seq.empty - where - helper :: Int -> Seq.Seq Int -> [Int] -> Maybe [Int] - helper sectionSum section rest = case compare sectionSum target of - EQ -> Just $ toList section - GT -> case Seq.viewl section of - Seq.EmptyL -> Nothing -- Should only happen if sTarget is negative - l Seq.:< ls -> helper (sectionSum - l) ls rest - LT -> case rest of - [] -> Nothing -- Can happen if no sequence of correct sum is found - (r:rs) -> helper (sectionSum + r) (section Seq.|> r) rs +continuousSubsequences :: [a] -> [[a]] +continuousSubsequences = filter (not . null) . concatMap tails . inits + +findRanges :: Int -> [Int] -> [[Int]] +findRanges target = filter ((== target) . sum) . continuousSubsequences solver :: [Int] -> IO () solver nums = do @@ -53,7 +32,7 @@ solver nums = do putStrLn "" putStrLn ">> Part 2" - let weakness = fromJust $ findRange invalidN nums + let weakness = head $ findRanges invalidN nums print $ minimum weakness + maximum weakness day :: Day