44 lines
1.7 KiB
Haskell
Raw Normal View History

2025-12-08 13:32:15 +00:00
module Puzzles.Day7 (puzzle) where
import Pre
2025-12-08 16:49:57 +00:00
import Data.IntMap qualified as IM
2025-12-08 16:34:30 +00:00
import Data.IntSet qualified as IS
2025-12-08 13:32:15 +00:00
puzzle :: Puzzle
puzzle =
Puzzle
{ number = 7
, parser = const do
2025-12-08 16:34:30 +00:00
line1 <- some $ (single '.' $> False) <|> (single 'S' $> True)
start <- maybe (fail "start not found") (pure . fst) $ find snd $ zip [0 ..] line1
void newline
rows <- (some $ (single '.' $> False) <|> (single '^' $> True)) `sepEndBy1` newline
let splitters = map (IS.fromList . map fst . filter snd . zip [0 ..]) rows
pure (start, splitters)
2025-12-08 13:32:15 +00:00
, parts =
2025-12-08 16:34:30 +00:00
[ uncurry \start ->
flip execState (0 :: Int)
2025-12-08 16:34:30 +00:00
. foldlM
( \beams splitters ->
IS.fromList . concat <$> for (IS.toList beams) \x -> do
let hit = x `IS.member` splitters
when hit $ modify succ
pure if hit then [x - 1, x + 1] else [x]
)
(IS.singleton start)
2025-12-08 16:49:57 +00:00
, uncurry \start ->
sum
2025-12-08 16:49:57 +00:00
. map snd
. IM.toList
. foldl
( \beams splitters ->
IM.fromListWith (+) . concat $ flip map (IM.toList beams) \(x, n) -> do
let hit = x `IS.member` splitters
zip (if hit then [x - 1, x + 1] else [x]) (repeat n)
)
(IM.singleton start (1 :: Int))
2025-12-08 13:32:15 +00:00
]
, extraTests = mempty
}