[hs] Clean up 2020_09

This commit is contained in:
Joscha 2020-12-09 12:30:42 +00:00
parent a80b3f70d2
commit 45f5f8a30e

View file

@ -1,9 +1,15 @@
{-# LANGUAGE RecordWildCards #-}
module Aoc.Y2020.D09 module Aoc.Y2020.D09
( day ( day
) where ) where
import Control.Monad 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
@ -25,15 +31,31 @@ isValid nums n = not $ null $ do
guard $ a + b == n guard $ a + b == n
pure () pure ()
-- Fast enough to give me a result, but not linear time. I couldn't figure out a data State = State
-- way to implement the linear time algorithm that didn't look like a mess. { sTarget :: Int
-- Maybe I'll have another go for the cleanup. , sSeq :: Seq.Seq Int
findRange :: Int -> [Int] -> [Int] , sSum :: Int
findRange n , sRest :: [Int]
= head } deriving (Show)
. filter ((== n) . sum)
. map (head . dropWhile ((< n) . sum) . inits) newState :: Int -> [Int] -> State
. tails newState target = State target Seq.empty 0
step :: State -> Either (Maybe [Int]) State
step s@State{..} = case compare sSum sTarget of
EQ -> Left $ Just $ toList sSeq
GT -> case Seq.viewl sSeq of
Seq.EmptyL -> Left Nothing -- Should only happen if sTarget is negative
l Seq.:< ls -> Right s{ sSeq = ls, sSum = sSum - l }
LT -> case sRest of
[] -> Left Nothing -- Can happen if no sequence of correct sum is found
(r:rs) -> Right s{ sSeq = sSeq Seq.|> r, sSum = sSum + r, sRest = rs }
untilLeft :: (b -> Either a b) -> b -> a
untilLeft f a = either id (untilLeft f) $ f a
findRange :: Int -> [Int] -> Maybe [Int]
findRange target nums = untilLeft step $ newState target nums
solver :: [Int] -> IO () solver :: [Int] -> IO ()
solver nums = do solver nums = do
@ -43,7 +65,7 @@ solver nums = do
putStrLn "" putStrLn ""
putStrLn ">> Part 2" putStrLn ">> Part 2"
let weakness = findRange invalidN nums let weakness = fromJust $ findRange invalidN nums
print $ minimum weakness + maximum weakness print $ minimum weakness + maximum weakness
day :: Day day :: Day