[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.D06 as D06
import qualified Aoc.Y2020.D07 as D07 import qualified Aoc.Y2020.D07 as D07
import qualified Aoc.Y2020.D08 as D08 import qualified Aoc.Y2020.D08 as D08
import qualified Aoc.Y2020.D09 as D09
year :: Year year :: Year
year = Year 2020 year = Year 2020
@ -22,4 +23,5 @@ year = Year 2020
, ( 6, D06.day) , ( 6, D06.day)
, ( 7, D07.day) , ( 7, D07.day)
, ( 8, D08.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