Skip to content
This repository was archived by the owner on Nov 17, 2024. It is now read-only.

Commit c0d3c8c

Browse files
committed
added contiguous regions finder
1 parent 9d08484 commit c0d3c8c

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

src/AOC/Common/Point.hs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ module AOC.Common.Point (
3939
, boundingBox'
4040
, inBoundingBox
4141
, minCorner, minCorner'
42+
, contiguousRegions
4243
, shiftToZero
4344
, shiftToZero'
4445
, parseAsciiMap
@@ -171,6 +172,26 @@ fullNeighbsSet p = S.fromDistinctAscList $
171172
, d /= pure 0
172173
]
173174

175+
-- | Find contiguous regions by cardinal neighbors
176+
contiguousRegions
177+
:: Set Point
178+
-> Set (Set Point)
179+
contiguousRegions = startNewPool S.empty
180+
where
181+
startNewPool seenPools remaining = case S.minView remaining of
182+
Nothing -> seenPools
183+
Just (x, xs) ->
184+
let (newPool, remaining') = fillUp (NES.singleton x) S.empty xs
185+
in startNewPool (S.insert newPool seenPools) remaining'
186+
fillUp boundary internal remaining = case NES.nonEmptySet newBoundary of
187+
Nothing -> (newInternal, remaining)
188+
Just nb -> fillUp nb newInternal newRemaining
189+
where
190+
edgeCandidates = foldMap' cardinalNeighbsSet boundary `S.difference` internal
191+
newBoundary = edgeCandidates `S.intersection` remaining
192+
newInternal = internal `S.union` NES.toSet boundary
193+
newRemaining = remaining `S.difference` edgeCandidates
194+
174195
memoPoint :: Memo Point
175196
memoPoint = Memo.wrap (uncurry V2) (\(V2 x y) -> (x, y)) $
176197
Memo.pair Memo.integral Memo.integral

0 commit comments

Comments
 (0)