Skip to content

Commit 6fe2863

Browse files
committed
Add function Grid.subGridAt()
* It provides a view of a portion of the Grid. * Use the SimpleCharGrid class instead of the simpleCharGridOf() function which was redundant.
1 parent 4ff9701 commit 6fe2863

File tree

2 files changed

+46
-22
lines changed
  • src
    • main/kotlin/de/ronny_h/aoc/extensions/grids
    • test/kotlin/de/ronny_h/aoc/extensions/grids

2 files changed

+46
-22
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ abstract class Grid<T>(
8181
grid[position.row][position.col] = element
8282
}
8383

84+
/**
85+
* @return a view of the portion of this Grid between the specified [row], [col] (inclusive) and [row] + [height], [col] + [width] (exclusive).
86+
* The returned list of lists is backed by this Grid, so non-structural changes in the returned list are reflected
87+
* in this Grid, and vice-versa.
88+
* Structural changes in the base Grid make the behavior of the view undefined.
89+
*/
90+
fun subGridAt(row: Int, col: Int, height: Int, width: Int = height): List<List<T>> {
91+
return buildList {
92+
for (r in row..<row + height) {
93+
add(grid[r].subList(col, col + width))
94+
}
95+
}
96+
}
97+
8498
fun <R> forEachIndex(action: (row: Int, col: Int) -> R): Sequence<R> = sequence {
8599
for (row in grid.indices) {
86100
for (col in grid[0].indices) {

src/test/kotlin/de/ronny_h/aoc/extensions/grids/GridTest.kt

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.ronny_h.aoc.extensions.grids
22

33
import com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOut
4+
import de.ronny_h.aoc.extensions.asList
45
import io.kotest.assertions.throwables.shouldThrow
56
import io.kotest.core.spec.style.StringSpec
67
import io.kotest.data.forAll
@@ -10,15 +11,11 @@ import io.kotest.matchers.shouldNotBe
1011

1112
class GridTest : StringSpec() {
1213

13-
private fun simpleCharGridOf(input: List<String>) = object : Grid<Char>(input, ' ') {
14-
override fun Char.toElementType() = this
15-
}
16-
1714
private val newLine: String = System.lineSeparator()
1815

1916
init {
2017
"a grid can be constructed from List of String" {
21-
val grid = simpleCharGridOf(listOf("12", "34"))
18+
val grid = SimpleCharGrid(listOf("12", "34"))
2219
grid shouldNotBe null
2320
}
2421

@@ -33,13 +30,13 @@ class GridTest : StringSpec() {
3330
}
3431

3532
"width and height have the right values" {
36-
val grid = simpleCharGridOf(listOf("00", "00", "00"))
33+
val grid = SimpleCharGrid(listOf("00", "00", "00"))
3734
grid.height shouldBe 3
3835
grid.width shouldBe 2
3936
}
4037

4138
"charAt returns the input values from the right indices" {
42-
val grid = simpleCharGridOf(listOf("12", "34"))
39+
val grid = SimpleCharGrid(listOf("12", "34"))
4340
grid[0, 0] shouldBe '1'
4441
grid[0, 1] shouldBe '2'
4542
grid[1, 0] shouldBe '3'
@@ -57,15 +54,15 @@ class GridTest : StringSpec() {
5754
}
5855

5956
"charAt with indices returns the same as charAt with Coordinates" {
60-
val grid = simpleCharGridOf(listOf("12", "34"))
57+
val grid = SimpleCharGrid(listOf("12", "34"))
6158
grid[0, 0] shouldBe grid.getAt(Coordinates(0, 0))
6259
grid[0, 1] shouldBe grid.getAt(Coordinates(0, 1))
6360
grid[1, 0] shouldBe grid.getAt(Coordinates(1, 0))
6461
grid[1, 1] shouldBe grid.getAt(Coordinates(1, 1))
6562
}
6663

6764
"charAt with index out of the input values returns the nullElement of a Char Grid" {
68-
val grid = simpleCharGridOf(listOf("12", "34"))
65+
val grid = SimpleCharGrid(listOf("12", "34"), ' ')
6966
grid[-1, 0] shouldBe ' '
7067
grid[0, 2] shouldBe ' '
7168
grid[1, -1] shouldBe ' '
@@ -83,24 +80,37 @@ class GridTest : StringSpec() {
8380
}
8481

8582
"setAt sets the element at the given coordinates" {
86-
val grid = simpleCharGridOf(listOf("12", "34"))
83+
val grid = SimpleCharGrid(listOf("12", "34"))
8784
grid.setAt(Coordinates(1, 0), '5')
8885
grid[0, 0] shouldBe '1'
8986
grid[0, 1] shouldBe '2'
9087
grid[1, 0] shouldBe '5'
9188
grid[1, 1] shouldBe '4'
9289
}
9390

91+
"subGridAt returns a sub grid at the given coordinates" {
92+
val input = """
93+
1234
94+
5678
95+
90AB
96+
CDEF
97+
""".asList()
98+
SimpleCharGrid(input).subGridAt(1, 1, 2) shouldBe listOf(
99+
listOf('6', '7'),
100+
listOf('0', 'A'),
101+
)
102+
}
103+
94104
"forEachIndex calls the provided function on each element in the expected order" {
95-
val grid = simpleCharGridOf(listOf("12", "34"))
105+
val grid = SimpleCharGrid(listOf("12", "34"))
96106
val chars = grid.forEachIndex { row, column ->
97107
grid[row, column]
98108
}.toList()
99109
chars shouldBe listOf('1', '2', '3', '4')
100110
}
101111

102112
"forEachElement calls the provided function on each element in the expected order" {
103-
val grid = simpleCharGridOf(listOf("12", "34"))
113+
val grid = SimpleCharGrid(listOf("12", "34"))
104114
val strings = grid.forEachElement { row, column, char ->
105115
"$row,$column:$char"
106116
}.toList()
@@ -114,7 +124,7 @@ class GridTest : StringSpec() {
114124
}
115125

116126
"find() finds all Coordinates" {
117-
val grid = simpleCharGridOf(listOf("12", "34"))
127+
val grid = SimpleCharGrid(listOf("12", "34"))
118128
forAll(
119129
row('1', Coordinates(0, 0)),
120130
row('2', Coordinates(0, 1)),
@@ -127,21 +137,21 @@ class GridTest : StringSpec() {
127137

128138
"find() throws a NoSuchElementException if the value cannot be found" {
129139
shouldThrow<NoSuchElementException> {
130-
simpleCharGridOf(listOf("12", "34")).find('5')
140+
SimpleCharGrid(listOf("12", "34")).find('5')
131141
}
132142
}
133143

134144
"printGrid prints the grid" {
135145
val output = tapSystemOut {
136-
val grid = simpleCharGridOf(listOf("12", "34"))
146+
val grid = SimpleCharGrid(listOf("12", "34"))
137147
grid.printGrid()
138148
}
139149
output shouldBe "12${newLine}34$newLine"
140150
}
141151

142152
"printGrid overrides specified coordinates" {
143153
val output = tapSystemOut {
144-
val grid = simpleCharGridOf(listOf("12", "34"))
154+
val grid = SimpleCharGrid(listOf("12", "34"))
145155
grid.printGrid(
146156
setOf(Coordinates(0, 1), Coordinates(1, 0))
147157
)
@@ -151,7 +161,7 @@ class GridTest : StringSpec() {
151161

152162
"printGrid overrides specified coordinates with given overrideChar" {
153163
val output = tapSystemOut {
154-
val grid = simpleCharGridOf(listOf("12", "34"))
164+
val grid = SimpleCharGrid(listOf("12", "34"))
155165
grid.printGrid(
156166
setOf(Coordinates(0, 1), Coordinates(1, 0)),
157167
'?'
@@ -162,7 +172,7 @@ class GridTest : StringSpec() {
162172

163173
"printGrid highlights specified coordinates with given highlightDirection's Char" {
164174
val output = tapSystemOut {
165-
val grid = simpleCharGridOf(listOf("12", "34"))
175+
val grid = SimpleCharGrid(listOf("12", "34"))
166176
grid.printGrid(
167177
highlightPosition = Coordinates(0, 1),
168178
highlightDirection = Direction.SOUTH
@@ -173,7 +183,7 @@ class GridTest : StringSpec() {
173183

174184
"printGrid - highlight has higher priority than overrides" {
175185
val output = tapSystemOut {
176-
val grid = simpleCharGridOf(listOf("12", "34"))
186+
val grid = SimpleCharGrid(listOf("12", "34"))
177187
grid.printGrid(
178188
overrides = setOf(Coordinates(0, 1)),
179189
highlightPosition = Coordinates(0, 1),
@@ -185,7 +195,7 @@ class GridTest : StringSpec() {
185195

186196
"printGrid - highlight without a direction falls back to overrides" {
187197
val output = tapSystemOut {
188-
val grid = simpleCharGridOf(listOf("12", "34"))
198+
val grid = SimpleCharGrid(listOf("12", "34"))
189199
grid.printGrid(
190200
overrides = setOf(Coordinates(0, 1)),
191201
highlightPosition = Coordinates(0, 1),
@@ -195,12 +205,12 @@ class GridTest : StringSpec() {
195205
}
196206

197207
"toString returns a string representation without any overrides" {
198-
val grid = simpleCharGridOf(listOf("12", "34"))
208+
val grid = SimpleCharGrid(listOf("12", "34"))
199209
grid.toString() shouldBe "12${newLine}34"
200210
}
201211

202212
"toString with overrides returns a string representation with the given overrides" {
203-
val grid = simpleCharGridOf(listOf("12", "34"))
213+
val grid = SimpleCharGrid(listOf("12", "34"))
204214
grid.toString(setOf(Coordinates(1, 1)), 'o') shouldBe "12${newLine}3o"
205215
}
206216
}

0 commit comments

Comments
 (0)