From: Neil Smith Date: Tue, 12 Dec 2023 23:06:35 +0000 (+0000) Subject: Work in progress X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=3395b9ffa7bbed788db830f7ad707148f8a38a46;p=advent-of-code-23.git Work in progress --- diff --git a/advent12/Main.hs b/advent12/Main.hs index 78af0a1..fc0580c 100644 --- a/advent12/Main.hs +++ b/advent12/Main.hs @@ -3,15 +3,14 @@ import AoC import Data.Text (Text) import qualified Data.Text.IO as TIO -import Data.Attoparsec.Text -- hiding (take) +import Data.Attoparsec.Text hiding (take, takeWhile) import Control.Applicative import Data.List import qualified Data.Map.Strict as M import Data.Maybe -import Control.Monad.State.Strict -data Spring = Unknown | Damaged | Operational deriving (Show, Eq) -data Record = Record [Spring] [Int] deriving (Show) +data Spring = Unknown | Damaged | Operational deriving (Show, Eq, Ord) +data Record = Record [Spring] [Int] deriving (Show, Eq, Ord) type Cache = M.Map Record Int -- type CacheState = State Cache @@ -29,11 +28,11 @@ main = -- print $ fmap countViableAssignments records print $ part1 records print $ unfoldRecord $ head records - print $ part2 records + -- print $ part2 records -part1, part2 :: [Record] -> Int +part1 :: [Record] -> Int part1 = sum . fmap countViableAssignments -part2 = sum . fmap (countViableAssignments . unfoldRecord) +-- part2 = sum . fmap (countViableAssignments . unfoldRecord) unfoldRecord :: Record -> Record unfoldRecord (Record springs signature) = Record uSprings uSignature @@ -41,13 +40,58 @@ unfoldRecord (Record springs signature) = Record uSprings uSignature uSignature = concat $ replicate 5 signature -countViable :: Record -> CacheState Int + +initialCache :: Record -> Cache +initialCache (Record springs signature) = M.union lastOperational cache0 + where cache0 = M.union sprs sigs + sprs = M.fromList $ fmap (\s -> (Record s [], 0)) $ tails springs + sigs = M.fromList $ fmap (\g -> (Record [] g, 0)) $ tails signature + lastOperationalChunk = + reverse $ takeWhile isPossOperational $ reverse springs + lastOperational = + M.fromList $ fmap (\s -> (Record s [], 1)) $ tails lastOperationalChunk + +isPossOperational :: Spring -> Bool +isPossOperational Operational = True +isPossOperational Unknown = True +isPossOperational _ = False + +isPossDamaged :: Spring -> Bool +isPossDamaged Damaged = True +isPossDamaged Unknown = True +isPossDamaged _ = False + +possibleDamagedChunk :: [Spring] -> Int -> Bool +possibleDamagedChunk springs n = + isDamagedChunk && ((null afterChunk) || (possOperational $ head afterChunk)) + where isDamagedChunk = (length $ filter isPossDamaged $ take n springs) == n + afterChunk = take 1 $ drop n springs + + +-- countViable previousSprings (Record (s:springs) (g:signature)) = + + +-- count: either consume this group or not + + +-- cache is how many ways to assign unknowns, leaving this partial record. +-- first item of springs is unknown or damaged +-- count = count_consuming_group + count_leaving_group +-- if first spring is damaged: count = count_consuming_group + + + +-- if first spring is damaged and next few springs can match next group: +-- consume springs (including all following operational ones), consume group +-- Add to cache: record' -> cache ! original +-- return countViable record' +-- if first spring is unknown +-- assume it's damaged, consume springs, consume group + -countViable previousSprings (Record (s:springs) (g:signature)) = --- if next few springs can match next group: -- countViable (springs after group) (tail groups) + countViable (tail springs) groups -- else -- countViable (tail springs) groups