Skip to content

Commit 331fc71

Browse files
committed
Pull up clusterRegions() to the general Grid
... and generalize it to type T.
1 parent 79b2d47 commit 331fc71

File tree

2 files changed

+37
-30
lines changed

2 files changed

+37
-30
lines changed

src/main/kotlin/de/ronny_h/aoc/extensions/grids/Grid.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,41 @@ abstract class Grid<T>(
188188

189189
return aStarAllPaths(start, { this == goal }, neighbours, d, h)
190190
}
191+
192+
/**
193+
* Clusters all cells into regions of adjacent cells having the same value.
194+
*
195+
* @param value If specified, only cells with that value are taken into account. Else, all cells get clustered.
196+
*
197+
* @return A list containing one list of [Coordinates] per cluster.
198+
*/
199+
fun clusterRegions(value: T? = null): List<List<Coordinates>> {
200+
val assigned = mutableSetOf<Coordinates>()
201+
return forEachCoordinates { position, element ->
202+
if ((value == null || element == value) && position !in assigned) {
203+
val region = collectRegionAt(position, element)
204+
assigned.addAll(region)
205+
region
206+
} else {
207+
null
208+
}
209+
}
210+
.filterNotNull()
211+
.toList()
212+
}
213+
214+
private fun collectRegionAt(
215+
position: Coordinates,
216+
value: T,
217+
visited: MutableSet<Coordinates> = mutableSetOf(position),
218+
regionsCoordinates: MutableList<Coordinates> = mutableListOf(position),
219+
): List<Coordinates> {
220+
position.neighbours().forEach { coordinates ->
221+
if (getAt(coordinates) == value && visited.add(coordinates)) {
222+
regionsCoordinates.add(coordinates)
223+
collectRegionAt(coordinates, value, visited, regionsCoordinates)
224+
}
225+
}
226+
return regionsCoordinates
227+
}
191228
}

src/main/kotlin/de/ronny_h/aoc/extensions/grids/SimpleCharGrid.kt

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,4 @@ package de.ronny_h.aoc.extensions.grids
33

44
open class SimpleCharGrid(input: List<String>, nullElement: Char = '#') : Grid<Char>(input, nullElement) {
55
override fun Char.toElementType() = this
6-
7-
fun clusterRegions(char: Char? = null): List<List<Coordinates>> {
8-
val assigned = mutableSetOf<Coordinates>()
9-
return forEachCoordinates { position, element ->
10-
if ((char == null || element == char) && position !in assigned) {
11-
val region = collectRegionAt(position, element)
12-
assigned.addAll(region)
13-
region
14-
} else {
15-
null
16-
}
17-
}
18-
.filterNotNull()
19-
.toList()
20-
}
21-
22-
private fun collectRegionAt(
23-
position: Coordinates,
24-
char: Char,
25-
visited: MutableSet<Coordinates> = mutableSetOf(position),
26-
regionsCoordinates: MutableList<Coordinates> = mutableListOf(position),
27-
): List<Coordinates> {
28-
position.neighbours().forEach { coordinates ->
29-
if (getAt(coordinates) == char && visited.add(coordinates)) {
30-
regionsCoordinates.add(coordinates)
31-
collectRegionAt(coordinates, char, visited, regionsCoordinates)
32-
}
33-
}
34-
return regionsCoordinates
35-
}
366
}

0 commit comments

Comments
 (0)