[hs] Solve 2020_09

This commit is contained in:
Joscha 2020-12-09 11:55:55 +00:00
parent 9b4e139030
commit a80b3f70d2
2 changed files with 52 additions and 0 deletions

50
hs/src/Aoc/Y2020/D09.hs Normal file
View file

@ -0,0 +1,50 @@
module Aoc.Y2020.D09
( day
) where
import Control.Monad
import Data.List
import Aoc.Day
import Aoc.Parse
parser :: Parser [Int]
parser = manyLines decimal
splitAndGroup :: Int -> [Int] -> [([Int], Int)]
splitAndGroup width
= map (\l -> (take width l, l !! width))
. filter ((> width) . length)
. tails
isValid :: [Int] -> Int -> Bool
isValid nums n = not $ null $ do
a <- nums
b <- nums
guard $ a /= b
guard $ a + b == n
pure ()
-- Fast enough to give me a result, but not linear time. I couldn't figure out a
-- way to implement the linear time algorithm that didn't look like a mess.
-- Maybe I'll have another go for the cleanup.
findRange :: Int -> [Int] -> [Int]
findRange n
= head
. filter ((== n) . sum)
. map (head . dropWhile ((< n) . sum) . inits)
. tails
solver :: [Int] -> IO ()
solver nums = do
putStrLn ">> Part 1"
let (_, invalidN) = head $ dropWhile (uncurry isValid) $ splitAndGroup 25 nums
print invalidN
putStrLn ""
putStrLn ">> Part 2"
let weakness = findRange invalidN nums
print $ minimum weakness + maximum weakness
day :: Day
day = dayParse parser solver