[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:
parent
9b34aafbb2
commit
f642872ea1
1 changed files with 10 additions and 31 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue