Skip to content

Commit

Permalink
Day 6: Use bitset in part 1, don't mutate in part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemient committed Jan 7, 2025
1 parent 7e6f747 commit 5d43f88
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions hs/src/Day6.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Day6 (part1, part2) where

import Control.Monad (ap)
import Control.Parallel.Strategies (parMap, rseq)
import Data.Array.Unboxed (UArray, inRange, listArray, range, (!), (//))
import Data.Array.Unboxed (UArray, inRange, listArray, range, (!))
import Data.Containers.ListUtils (nubOrd)
import Data.Ix (Ix)
import Data.Maybe (catMaybes, isJust)
Expand Down Expand Up @@ -46,17 +46,19 @@ visited bounds isBlock start = catMaybes $ takeWhile isJust $ iterate (>>= step)
pos' = (y + dy, x + dx)

part1 :: Text -> Int
part1 input = length $ nubOrd $ map fst $ start >>= visited bounds (`Set.member` blocks)
part1 input = length $ nubOrd $ map fst $ start >>= visited bounds (blocks' !)
where
(bounds, blocks, start) = parse input
blocks' = listArray @UArray bounds $ (`Set.member` blocks) <$> range bounds

part2 :: Text -> Int
part2 input =
length $ filter id $ start >>= (parMap rseq . isLoop) `ap` (nubOrd . map fst . visited bounds (blocks' !))
where
(bounds, blocks, start) = parse input
blocks' = listArray @UArray bounds $ (`Set.member` blocks) <$> range bounds
isLoop start' block = isLoop' 0 Set.empty $ visited bounds (blocks' // [(block, True)] !) start'
isBlock block pos = pos == block || blocks' ! pos
isLoop start' block = isLoop' 0 Set.empty $ visited bounds (isBlock block) start'
isLoop' _ _ [] = False
isLoop' (-1) seen ((_, (dy, _)) : rest) = isLoop' dy seen rest
isLoop' _ seen ((pos, (-1, _)) : rest) = pos `Set.member` seen || isLoop' (-1) (Set.insert pos seen) rest
Expand Down

0 comments on commit 5d43f88

Please sign in to comment.