[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

View file

@ -11,6 +11,7 @@ import qualified Aoc.Y2020.D05 as D05
import qualified Aoc.Y2020.D06 as D06
import qualified Aoc.Y2020.D07 as D07
import qualified Aoc.Y2020.D08 as D08
import qualified Aoc.Y2020.D09 as D09
year :: Year
year = Year 2020
@ -22,4 +23,5 @@ year = Year 2020
, ( 6, D06.day)
, ( 7, D07.day)
, ( 8, D08.day)
, ( 9, D09.day)
]

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