[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
|
module Aoc.Y2020.D09
|
||||||
( day
|
( day
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad
|
|
||||||
import Data.Foldable
|
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
|
||||||
|
|
||||||
import qualified Data.Sequence as Seq
|
|
||||||
|
|
||||||
import Aoc.Day
|
import Aoc.Day
|
||||||
import Aoc.Parse
|
import Aoc.Parse
|
||||||
|
|
@ -18,32 +11,18 @@ parser :: Parser [Int]
|
||||||
parser = manyLines decimal
|
parser = manyLines decimal
|
||||||
|
|
||||||
splitAndGroup :: Int -> [Int] -> [([Int], Int)]
|
splitAndGroup :: Int -> [Int] -> [([Int], Int)]
|
||||||
splitAndGroup width
|
splitAndGroup width xs = case splitAt width xs of
|
||||||
= map (\l -> (take width l, l !! width))
|
(_, []) -> []
|
||||||
. filter ((> width) . length)
|
(as, b:_) -> (as, b) : splitAndGroup width (drop 1 xs)
|
||||||
. tails
|
|
||||||
|
|
||||||
isValid :: [Int] -> Int -> Bool
|
isValid :: [Int] -> Int -> Bool
|
||||||
isValid nums n = not $ null $ do
|
isValid nums n = elem n $ (+) <$> nums <*> nums
|
||||||
a <- nums
|
|
||||||
b <- nums
|
|
||||||
guard $ a /= b
|
|
||||||
guard $ a + b == n
|
|
||||||
pure ()
|
|
||||||
|
|
||||||
-- Only works if all numbers are positive.
|
continuousSubsequences :: [a] -> [[a]]
|
||||||
findRange :: Int -> [Int] -> Maybe [Int]
|
continuousSubsequences = filter (not . null) . concatMap tails . inits
|
||||||
findRange target = helper 0 Seq.empty
|
|
||||||
where
|
findRanges :: Int -> [Int] -> [[Int]]
|
||||||
helper :: Int -> Seq.Seq Int -> [Int] -> Maybe [Int]
|
findRanges target = filter ((== target) . sum) . continuousSubsequences
|
||||||
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
|
|
||||||
|
|
||||||
solver :: [Int] -> IO ()
|
solver :: [Int] -> IO ()
|
||||||
solver nums = do
|
solver nums = do
|
||||||
|
|
@ -53,7 +32,7 @@ solver nums = do
|
||||||
|
|
||||||
putStrLn ""
|
putStrLn ""
|
||||||
putStrLn ">> Part 2"
|
putStrLn ">> Part 2"
|
||||||
let weakness = fromJust $ findRange invalidN nums
|
let weakness = head $ findRanges invalidN nums
|
||||||
print $ minimum weakness + maximum weakness
|
print $ minimum weakness + maximum weakness
|
||||||
|
|
||||||
day :: Day
|
day :: Day
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue