[hs] Solve 2020_09
This commit is contained in:
parent
9b4e139030
commit
a80b3f70d2
2 changed files with 52 additions and 0 deletions
|
|
@ -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
50
hs/src/Aoc/Y2020/D09.hs
Normal 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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue