From bc96d2ec4aca164cca68dc3fc144b033cd4d39d0 Mon Sep 17 00:00:00 2001 From: justin Date: Tue, 12 Dec 2023 06:48:05 +0000 Subject: [PATCH] day 12 in progress --- src/AOC/Challenge/Day12.hs | 180 ++++++++++++++++++++++++++++++------- test-data/2023/12a.txt | 7 ++ test-data/2023/12b.txt | 12 +++ 3 files changed, 169 insertions(+), 30 deletions(-) create mode 100644 test-data/2023/12a.txt create mode 100644 test-data/2023/12b.txt diff --git a/src/AOC/Challenge/Day12.hs b/src/AOC/Challenge/Day12.hs index 9b7710b..ed0555f 100644 --- a/src/AOC/Challenge/Day12.hs +++ b/src/AOC/Challenge/Day12.hs @@ -1,4 +1,4 @@ -{-# OPTIONS_GHC -Wno-unused-imports #-} +{-# OPTIONS_GHC -Wno-unused-imports #-} {-# OPTIONS_GHC -Wno-unused-top-binds #-} -- | @@ -20,41 +20,161 @@ -- types @_ :~> _@ with the actual types of inputs and outputs of the -- solution. You can delete the type signatures completely and GHC -- will recommend what should go in place of the underscores. +module AOC.Challenge.Day12 + ( day12a, + day12b, + combosOf, + ) +where -module AOC.Challenge.Day12 ( - -- day12a - -- , day12b - ) where +import AOC.Prelude +import Data.Bitraversable +import qualified Data.Graph.Inductive as G +import qualified Data.IntMap as IM +import qualified Data.IntSet as IS +import qualified Data.List.NonEmpty as NE +import qualified Data.List.PointedList as PL +import qualified Data.List.PointedList.Circular as PLC +import qualified Data.Map as M +import qualified Data.OrdPSQ as PSQ +import qualified Data.Sequence as Seq +import qualified Data.Set as S +import qualified Data.Text as T +import qualified Data.Vector as V +import qualified Linear as L +import qualified Text.Megaparsec as P +import qualified Text.Megaparsec.Char as P -import AOC.Prelude +-- #.#.### 1,1,3 -import qualified Data.Graph.Inductive as G -import qualified Data.IntMap as IM -import qualified Data.IntSet as IS -import qualified Data.List.NonEmpty as NE -import qualified Data.List.PointedList as PL -import qualified Data.List.PointedList.Circular as PLC -import qualified Data.Map as M -import qualified Data.OrdPSQ as PSQ -import qualified Data.Sequence as Seq -import qualified Data.Set as S -import qualified Data.Text as T -import qualified Data.Vector as V -import qualified Linear as L -import qualified Text.Megaparsec as P -import qualified Text.Megaparsec.Char as P -import qualified Text.Megaparsec.Char.Lexer as PP +parseChar = \case + '#' -> Just $ Just True + '.' -> Just $ Just False + '?' -> Just $ Nothing + _ -> Nothing + +-- ???.### 1,1,3 + +classify :: [Bool] -> [Int] +classify = filter (> 0) . map length . splitOn [False] + +combosOf :: Int -> [[(Int, Bool)]] +combosOf x = cacheMap IM.! x + where + cacheMap = + IM.fromList + [ ( i, + (map (\qs -> (length qs, head qs)) . group) + <$> replicateM i [False, True] + ) + | i <- [0 .. 100] + ] + +expandOut :: [(Int, Maybe Bool)] -> [[(Int, Bool)]] +expandOut = fmap (map rematch . fmap concat) . traverse $ \(i, b) -> case b of + Nothing -> combosOf i + Just x -> [[(i, x)]] + where + -- rematch [] = [] + rematch ((i,x0):xs) = go i x0 xs + where + go !n x = \case + [] -> [(n,x)] + (j,y):ys + | x == y -> go (n + j) x ys + | otherwise -> (n,x) : go j y ys + -- rematch = map (\qs -> (length qs, head qs)) . group . concatMap (\(i, x) -> replicate i x) + +-- expandOutMatches :: [Int] -> [(Int, Maybe Bool)] -> Int +-- -- [[(Int, Bool)]] +-- expandOutMatches = \case +-- [] -> \case +-- [] -> 1 +-- (_, Just False):xs -> expandOutMatches [] xs +-- (_, Just True):xs -> 0 +-- p:ps -> \case +-- [] -> 0 +-- (n, Just False):xs -> _ +-- (n, Just True):xs -> _ +-- -- p:ps -> \case +-- -- [] -> +-- -- fmap concat . traverse $ \(i, b) -> case b of +-- -- Nothing -> combosOf i +-- -- Just x -> [[(i, x)]] day12a :: _ :~> _ -day12a = MkSol - { sParse = Just . lines - , sShow = show - , sSolve = Just +day12a = + MkSol + { sParse = + traverse + ( bitraverse (traverse parseChar) (traverse (readMaybe @Int) . splitOn ",") + <=< listTup + . words + ) + . lines, + sShow = show, + sSolve = noFail $ + fmap sum . map $ \(xs :: [Maybe Bool], pat :: [Int]) -> + countTrue ((== pat) . classify) $ + traverse (\case Nothing -> [False, True]; Just x -> [x]) xs } +-- .??..??...?##..??..??...?##..??..??...?##..??..??...?##..??..??...?##. +-- 1,1,3,1,1,3,1,1,3,1,1,3,1,1,3 + +-- | New case: true = #, false = ? +chunkUp :: [Maybe Bool] -> [Seq Bool] +chunkUp = go + where + go = \case + [] -> [] + Just False:xs -> chunkUp xs + Just True:xs -> eatUp (Seq.singleton True) xs + Nothing:xs -> eatUp (Seq.singleton False) xs + eatUp qs = \case + [] -> [qs] + Just False:xs -> qs : go xs + Just True:xs -> eatUp (qs Seq.:|> True) xs + Nothing:xs -> eatUp (qs Seq.:|> False) xs + +chunkPatterns :: Seq Bool -> Set [Int] +chunkPatterns = S.fromList . map reChunk . traverse (\case True -> [True]; False -> [False,True]) + where + reChunk :: Seq Bool -> [Int] + reChunk = traceShowId . map length . filter (not . null) . splitOn [False] . toList + +-- consumeChunkPatterns :: [Int] -> [Set (NonEmpty Int)] -> Int +-- consumeChunkPatterns = \case +-- [] -> \case +-- [] -> 1 +-- -- at least one more to consume, so must fail +-- _:_ -> 0 +-- n:ns -> \case +-- [] -> 0 +-- x:xs -> _ +-- -- product +-- -- [ _ +-- -- ] + + day12b :: _ :~> _ -day12b = MkSol - { sParse = sParse day12a - , sShow = show - , sSolve = Just +day12b = + MkSol + { sParse = sParse day12a, + sShow = show, + sSolve = noFail $ + map $ \(xs :: [Maybe Bool], pat :: [Int]) -> + -- fmap sum . map $ \(xs :: [Maybe Bool], pat :: [Int]) -> + let pat' :: [Int] + pat' = concat $ replicate 5 pat + xs' :: [Maybe Bool] + xs' = intercalate [Nothing] $ replicate 5 xs + in head $ chunkPatterns <$> chunkUp xs' + -- in countTrue (matchesPat pat') $ + -- expandOut . map (\qs -> (length qs, head qs)) $ + -- group xs' + -- countTrue ((== pat') . classify) $ + -- traverse (\case Nothing -> [False,True]; Just x -> [x]) xs' } + where + matchesPat pat = (== pat) . map fst . filter snd diff --git a/test-data/2023/12a.txt b/test-data/2023/12a.txt new file mode 100644 index 0000000..d90183a --- /dev/null +++ b/test-data/2023/12a.txt @@ -0,0 +1,7 @@ +???.### 1,1,3 +.??..??...?##. 1,1,3 +?#?#?#?#?#?#?#? 1,3,1,6 +????.#...#... 4,1,1 +????.######..#####. 1,6,5 +?###???????? 3,2,1 +>>> 21 diff --git a/test-data/2023/12b.txt b/test-data/2023/12b.txt new file mode 100644 index 0000000..0c330cd --- /dev/null +++ b/test-data/2023/12b.txt @@ -0,0 +1,12 @@ +???.### 1,1,3 +>>> 1 +.??..??...?##. 1,1,3 +>>> 16384 +?#?#?#?#?#?#?#? 1,3,1,6 +>>> 1 +????.#...#... 4,1,1 +>>> 16 +????.######..#####. 1,6,5 +>>> 2500 +?###???????? 3,2,1 +>>> 506250