Skip to content

Commit 37bee39

Browse files
authored
Merge branch 'main' into patch-1
2 parents 07562d0 + 6cf39cc commit 37bee39

File tree

2 files changed

+90
-1
lines changed
  • src
    • main/kotlin/com/soberg/aoc/utlities/datastructures
    • test/kotlin/com/soberg/aoc/utlities/datastructures

2 files changed

+90
-1
lines changed

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ data class Grid2D<T>(
2121

2222
infix operator fun get(location: Location): T = grid[location.row][location.col]
2323

24-
fun get(row: Int, col: Int): T = grid[row][col]
24+
operator fun get(row: Int, col: Int): T = grid[row][col]
2525

2626
/** @return true if the specified [location] is in the bounds of this grid, false if not. */
2727
fun isInBounds(location: Location): Boolean = isInBounds(location.row, location.col)
@@ -44,6 +44,36 @@ data class Grid2D<T>(
4444
} else null
4545
}
4646

47+
/** @return The collection of elements (as a [List]) that exist from the start [from] (inclusive)
48+
* in [direction] for [numElementsToCollect], null if any location would be out of bounds of this grid.
49+
*
50+
* Note that [numElementsToCollect] is inclusive of the starting location - therefore, a value
51+
* of 1 would result in a single item list of just the element at [from]. */
52+
fun collect(
53+
from: Location,
54+
direction: Direction,
55+
numElementsToCollect: Int,
56+
) : List<T>? {
57+
val finalLocation = from.move(direction, numElementsToCollect - 1)
58+
if (!isInBounds(finalLocation)) {
59+
return null
60+
}
61+
return buildList {
62+
for (i in 0..<numElementsToCollect) {
63+
add(get(from.move(direction, i)))
64+
}
65+
}
66+
}
67+
68+
/** Walks through each location in this grid. */
69+
inline fun traverse(at: (location: Location) -> Unit) {
70+
for (row in 0..<rowSize) {
71+
for (col in 0..<colSize) {
72+
at(Location(row, col))
73+
}
74+
}
75+
}
76+
4777
/** @return A new copy of this [Grid2D] with the specified [element] replaced at [location].
4878
* @throws [IllegalArgumentException] if [location] not in bounds for this grid. */
4979
fun replace(location: Location, element: T): Grid2D<T> {
@@ -95,3 +125,8 @@ data class Grid2D<T>(
95125
}
96126

97127
fun <T> List<List<T>>.toGrid2D() = Grid2D(this)
128+
129+
/** Converts the common AoC input (List of lines (as String) from input file). */
130+
inline fun <T> List<String>.toGrid2D(convertLine: (String) -> List<T>) = map { line ->
131+
convertLine(line)
132+
}.toGrid2D()

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.soberg.aoc.utlities.datastructures
22

33
import assertk.assertThat
4+
import assertk.assertions.containsExactly
45
import assertk.assertions.hasMessage
56
import assertk.assertions.isEqualTo
67
import assertk.assertions.isFalse
8+
import assertk.assertions.isNotNull
79
import assertk.assertions.isNull
810
import assertk.assertions.isTrue
911
import com.soberg.aoc.utlities.datastructures.Grid2D.Direction
@@ -78,6 +80,58 @@ class Grid2DTest {
7880
)
7981
}
8082

83+
@Test
84+
fun `return expected elements for collect`() {
85+
val actual = testGrid.collect(Location(2, 1), Direction.East, 3)
86+
assertThat(actual)
87+
.isNotNull()
88+
.containsExactly(222, 333, 444)
89+
}
90+
91+
@Test
92+
fun `return null for collect when out of bounds`() {
93+
val actual = testGrid.collect(Location(2, 1), Direction.East, 4)
94+
assertThat(actual)
95+
.isNull()
96+
}
97+
98+
@Test
99+
fun `touch all locations in grid for traverse`() {
100+
val grid = listOf(
101+
listOf(1, 2, 3),
102+
listOf(4, 5, 6),
103+
).toGrid2D()
104+
val actualTouched = buildList {
105+
grid.traverse {
106+
add(it.row to it.col)
107+
}
108+
}
109+
assertThat(actualTouched)
110+
.containsExactly(
111+
0 to 0, 0 to 1, 0 to 2,
112+
1 to 0, 1 to 1, 1 to 2,
113+
)
114+
}
115+
116+
@Test
117+
fun `create expected grid from input`() {
118+
val grid = listOf(
119+
"ABC",
120+
"123",
121+
).toGrid2D { line ->
122+
line.toCharArray().asList()
123+
}
124+
assertThat(grid)
125+
.isEqualTo(
126+
Grid2D(
127+
listOf(
128+
listOf('A', 'B', 'C'),
129+
listOf('1', '2', '3'),
130+
)
131+
)
132+
)
133+
}
134+
81135
@Test
82136
fun `throw when attempting replace for out of bounds location`() {
83137
val exception = assertThrows<IllegalArgumentException> {

0 commit comments

Comments
 (0)