[hs] Shorten 2020_09

Using the plain brute-force approach leads to vastly simpler code at the cost of
some performance. Still pretty fast though.
This commit is contained in:
Joscha 2020-12-09 16:29:25 +00:00
parent 9b34aafbb2
commit f642872ea1

View file

@ -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