Skip to content

Commit a2e186d

Browse files
committed
Add asyncCount and Grid2D count methods
1 parent caa4d35 commit a2e186d

File tree

5 files changed

+79
-3
lines changed

5 files changed

+79
-3
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
object Publishing {
22
const val ArtifactId = "kotlin-aoc-utilities"
33
const val GroupId = "com.github.jsoberg"
4-
const val Version = "2025.1.1"
4+
const val Version = "2025.2"
55
}

src/main/kotlin/com/soberg/aoc/utlities/datastructures/Grid2D.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ data class Grid2D<T>(
133133
}
134134
}
135135

136+
/** Traverses each location in the grid, counting the true results of [at]. */
137+
inline fun count(at: (location: Location, element: T) -> Boolean): Int {
138+
var total = 0
139+
traverse { location ->
140+
if (at(location, get(location))) {
141+
total++
142+
}
143+
}
144+
return total
145+
}
146+
136147
/** Traverses each location in the grid, summing the result of [at]. */
137148
@OptIn(ExperimentalTypeInference::class)
138149
@OverloadResolutionByLambdaReturnType
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.soberg.aoc.utlities.extensions
2+
3+
import kotlinx.coroutines.CoroutineDispatcher
4+
import kotlinx.coroutines.Dispatchers
5+
import kotlinx.coroutines.coroutineScope
6+
import kotlinx.coroutines.launch
7+
import kotlinx.coroutines.runBlocking
8+
import java.util.concurrent.atomic.AtomicInteger
9+
10+
inline fun <T> Iterable<T>.asyncCountBlocking(
11+
dispatcher: CoroutineDispatcher = Dispatchers.Default,
12+
crossinline selector: (T) -> Boolean,
13+
): Int = runBlocking(dispatcher) {
14+
asyncCount(selector)
15+
}
16+
17+
suspend inline fun <T> Iterable<T>.asyncCount(crossinline selector: (T) -> Boolean): Int {
18+
val count = AtomicInteger()
19+
coroutineScope {
20+
forEach {
21+
launch {
22+
count.getAndAdd(if (selector(it)) 1 else 0)
23+
}
24+
}
25+
}
26+
return count.get()
27+
}

src/test/kotlin/com/soberg/aoc/utlities/datastructures/Grid2DTest.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ class Grid2DTest {
202202
}
203203

204204
@Test
205-
fun `result in expected sum for sumOf Int`() {
205+
fun `return expected sum for sumOf Int`() {
206206
val grid = listOf(
207207
listOf(1, 2, 3),
208208
listOf(4, 5, 6),
@@ -212,7 +212,7 @@ class Grid2DTest {
212212
}
213213

214214
@Test
215-
fun `result in expected sum for sumOf Long`() {
215+
fun `return expected sum for sumOf Long`() {
216216
val grid = listOf(
217217
listOf(Int.MAX_VALUE.toLong() + 1, 2L),
218218
listOf(4L, 5L),
@@ -221,6 +221,16 @@ class Grid2DTest {
221221
.isEqualTo(Int.MAX_VALUE.toLong() + 1 + 2 + 4 + 5)
222222
}
223223

224+
@Test
225+
fun `return expected count`() {
226+
val grid = listOf(
227+
listOf('A', 'T', 'P'),
228+
listOf('P', 'P', 'A'),
229+
).toGrid2D()
230+
assertThat(grid.count { _, element -> element == 'P' })
231+
.isEqualTo(3)
232+
}
233+
224234
@Test
225235
fun `return expected set of neighbors`() {
226236
assertThat(testGrid.neighbors(Location(0, 0), MainDirections))
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.soberg.aoc.utlities.extensions
2+
3+
import assertk.assertThat
4+
import assertk.assertions.isEqualTo
5+
import kotlinx.coroutines.test.runTest
6+
import org.junit.jupiter.api.Test
7+
8+
class AsyncCountTest {
9+
private val testData = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
10+
11+
@Test
12+
fun `return count - blocking`() {
13+
val underFive = testData.asyncCountBlocking {
14+
it < 5
15+
}
16+
17+
assertThat(underFive).isEqualTo(5)
18+
}
19+
20+
@Test
21+
fun `return count - coroutine`() = runTest {
22+
val overFive = testData.asyncCount {
23+
it > 5
24+
}
25+
26+
assertThat(overFive).isEqualTo(4)
27+
}
28+
}

0 commit comments

Comments
 (0)