commit eff0a03b28482b76bc2e3e7877ddfe3428529771
parent f52d5fc351e7563e8e75ef296e236679e1bef867
Author: Robert Russell <robert@rr3.xyz>
Date: Sun, 7 Dec 2025 22:02:18 -0800
Solve 07 Part 2
Diffstat:
2 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/07/Main.hs b/07/Main.hs
@@ -6,34 +6,47 @@ import Common.Matrix (Matrix)
import Common.Matrix qualified as M
import Common.Util ((.:))
import Control.Applicative
-import Data.Bool
import Data.ByteString qualified as BS
import Data.Functor
+import Data.Maybe
import Sparsec
import System.Exit (die)
--------------------------------------------------------------------------------
-- Solution
-data State = Empty | Source | ColdSplitter | HotSplitter | Beam deriving (Eq, Show)
+data State = Source | Void Int | Splitter Int deriving (Eq, Show)
-belowPowered :: Cellular State Bool
-belowPowered = any (`elem` [Source, Beam]) <$> C.neighbor (-1, 0)
+strength :: State -> Int
+strength = \case
+ Source -> 1
+ Void n -> n
+ Splitter _ -> 0
-besideHotSplitter :: Cellular State Bool
-besideHotSplitter = fmap (elem (Just HotSplitter)) . traverse C.neighbor $ [(0, -1), (0, 1)]
+reflectance :: State -> Int
+reflectance = \case
+ Source -> 0
+ Void _ -> 0
+ Splitter n -> n
+
+topPower :: Cellular State Int
+topPower = maybe 0 strength <$> C.neighbor (-1, 0)
+
+sidePower :: Cellular State Int
+sidePower = sum . map (maybe 0 reflectance) <$> traverse C.neighbor [(0, -1), (0, 1)]
tachyon :: Cellular State State
tachyon =
C.self >>= \case
- Empty -> bool Empty Beam .: (||) <$> belowPowered <*> besideHotSplitter
Source -> pure Source
- ColdSplitter -> bool ColdSplitter HotSplitter <$> belowPowered
- HotSplitter -> pure HotSplitter
- Beam -> pure Beam
+ Void _ -> Void .: (+) <$> topPower <*> sidePower
+ Splitter _ -> Splitter <$> topPower
part1 :: Matrix State -> Int
-part1 = M.count (== HotSplitter) . C.stabilize tachyon
+part1 = M.count ((> 0) . reflectance) . C.stabilize tachyon
+
+part2 :: Matrix State -> Int
+part2 m = sum . fmap strength . fromJust . M.row (M.nrows m - 1) . C.stabilize tachyon $ m
--------------------------------------------------------------------------------
-- Parsing
@@ -44,7 +57,7 @@ instance Utf8Error ParseError where
type P a = Parse ParseError a
pCell :: P State
-pCell = char '.' $> Empty <|> char 'S' $> Source <|> char '^' $> ColdSplitter
+pCell = char 'S' $> Source <|> char '.' $> Void 0 <|> char '^' $> Splitter 0
pRow :: P [State]
pRow = many pCell <* char '\n'
@@ -70,5 +83,4 @@ main :: IO ()
main = do
input <- getInput
print . part1 $ input
-
--- print . part2 $ input
+ print . part2 $ input
diff --git a/lib/Common/Matrix.hs b/lib/Common/Matrix.hs
@@ -1,4 +1,4 @@
-module Common.Matrix (Matrix, nrows, ncols, generate, fromList, (!?), count) where
+module Common.Matrix (Matrix, nrows, ncols, generate, fromList, (!?), row, count) where
import Common.Util (consensus)
import Data.Vector (Vector)
@@ -35,5 +35,14 @@ Matrix nr nc vs !? (i, j) =
then Just $ vs V.! (i * nc + j)
else Nothing
+row :: Int -> Matrix a -> Maybe (Vector a)
+row i (Matrix nr nc vs) =
+ if 0 <= i && i < nr
+ then Just (V.slice (i * nc) nc vs)
+ else Nothing
+
+-- TODO (requires copy)
+-- col :: Int -> Matrix a -> Maybe (Vector a)
+
count :: (a -> Bool) -> Matrix a -> Int
count p = V.length . V.filter p . valuesRowMajor