Skip to content

Commit e6a4ecc

Browse files
committed
Refactor Grid: Use x and y instead of col and row
... and bring them in their canonical order
1 parent d44828e commit e6a4ecc

File tree

10 files changed

+89
-89
lines changed

10 files changed

+89
-89
lines changed

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

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,65 +62,65 @@ abstract class Grid<T>(
6262
initGrid(input)
6363
}
6464

65-
protected fun initGrid(input: List<String>) = input.forEachIndexed { row, line ->
66-
line.forEachIndexed { col, char ->
67-
grid[row][col] = char.toElementType()
65+
protected fun initGrid(input: List<String>) = input.forEachIndexed { y, line ->
66+
line.forEachIndexed { x, char ->
67+
grid[y][x] = char.toElementType()
6868
}
6969
}
7070

7171
/**
7272
* @return The value at the specified cell.
7373
*/
74-
operator fun get(row: Int, col: Int): T {
74+
operator fun get(x: Int, y: Int): T {
7575
return grid
76-
.getOrNull(row)
77-
?.getOrNull(col)
76+
.getOrNull(y)
77+
?.getOrNull(x)
7878
?: fallbackElement
7979
}
8080

81-
operator fun set(row: Int, col: Int, value: T) {
82-
grid[row][col] = value
81+
operator fun set(x: Int, y: Int, value: T) {
82+
grid[y][x] = value
8383
}
8484

85-
fun getAt(position: Coordinates) = get(position.y, position.x)
85+
fun getAt(position: Coordinates) = get(position.x, position.y)
8686
fun setAt(position: Coordinates, element: T) {
87-
this[position.y, position.x] = element
87+
this.set(position.x, position.y, element)
8888
}
8989

9090
/**
91-
* @return a view of the portion of this Grid between the specified [row], [col] (inclusive) and [row] + [height], [col] + [width] (exclusive).
91+
* @return a view of the portion of this Grid between the specified [x], [y] (inclusive) and [x] + [width], [y] + [height] (exclusive).
9292
* The returned list of lists is backed by this Grid, so non-structural changes in the returned list are reflected
9393
* in this Grid, and vice-versa.
9494
* Structural changes in the base Grid make the behavior of the view undefined.
9595
*/
96-
fun subGridAt(row: Int, col: Int, height: Int, width: Int = height): List<List<T>> {
96+
fun subGridAt(x: Int, y: Int, width: Int, height: Int = width): List<List<T>> {
9797
return buildList {
98-
for (r in row..<row + height) {
99-
add(grid[r].subList(col, col + width))
98+
for (r in y..<y + height) {
99+
add(grid[r].subList(x, x + width))
100100
}
101101
}
102102
}
103103

104-
fun <R> forEachIndex(action: (row: Int, col: Int) -> R): Sequence<R> = sequence {
105-
for (row in grid.indices) {
106-
for (col in grid[0].indices) {
107-
yield(action(row, col))
104+
fun <R> forEachIndex(action: (x: Int, y: Int) -> R): Sequence<R> = sequence {
105+
for (y in grid.indices) {
106+
for (x in grid[0].indices) {
107+
yield(action(x, y))
108108
}
109109
}
110110
}
111111

112-
fun <R> forEachElement(action: (row: Int, col: Int, element: T) -> R): Sequence<R> = sequence {
113-
for (row in grid.indices) {
114-
for (col in grid[0].indices) {
115-
yield(action(row, col, get(row, col)))
112+
fun <R> forEachElement(action: (x: Int, y: Int, element: T) -> R): Sequence<R> = sequence {
113+
for (y in grid.indices) {
114+
for (x in grid[0].indices) {
115+
yield(action(x, y, get(x, y)))
116116
}
117117
}
118118
}
119119

120120
fun <R> forEachCoordinates(action: (position: Coordinates, element: T) -> R): Sequence<R> = sequence {
121-
for (row in grid.indices) {
122-
for (col in grid[0].indices) {
123-
yield(action(Coordinates(col, row), get(row, col)))
121+
for (y in grid.indices) {
122+
for (x in grid[0].indices) {
123+
yield(action(Coordinates(x, y), get(x, y)))
124124
}
125125
}
126126
}
@@ -130,8 +130,8 @@ abstract class Grid<T>(
130130
*
131131
* @throws NoSuchElementException If no matching element can be found.
132132
*/
133-
fun find(value: T): Coordinates = forEachElement { row, col, element ->
134-
if (element == value) Coordinates(col, row) else null
133+
fun find(value: T): Coordinates = forEachElement { x, y, element ->
134+
if (element == value) Coordinates(x, y) else null
135135
}.filterNotNull().first()
136136

137137
override fun toString(): String = toString(setOf())

src/main/kotlin/de/ronny_h/aoc/year2017/day21/FractalArt.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,17 @@ class FractalArtGrid(size: Int) : Grid<Char>(size, size, off) {
113113
}
114114

115115
private fun applyRuleAt(rule: Rule, start: Coordinates) {
116-
rule.replacement.forEachIndexed { row, rowString ->
117-
rowString.forEachIndexed { col, value ->
118-
this[start.y + row, start.x + col] = value
116+
rule.replacement.forEachIndexed { y, rowString ->
117+
rowString.forEachIndexed { x, value ->
118+
this[start.x + x, start.y + y] = value
119119
}
120120
}
121121
}
122122

123123
private fun forEachSquareOfSize(size: Int, block: (Coordinates, List<List<Char>>) -> Unit) {
124-
for (row in 0..<height step size) {
125-
for (col in 0..<height step size) {
126-
block(Coordinates(col, row), subGridAt(row, col, size))
124+
for (y in 0..<height step size) {
125+
for (x in 0..<height step size) {
126+
block(Coordinates(x, y), subGridAt(x, y, width = size))
127127
}
128128
}
129129
}

src/main/kotlin/de/ronny_h/aoc/year2018/day11/ChronalCharge.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ class PowerCellGrid(serialNumber: Int) : Grid<Int>(300, 300, -1000) {
1919
private val cache = mutableMapOf<Configuration, Int>()
2020

2121
init {
22-
forEachIndex { y, x ->
22+
forEachIndex { x, y ->
2323
val rackId = x + 10
2424
val powerLevel = rackId * y + serialNumber
2525
val hundredsDigit = (powerLevel * rackId).digit(3)
26-
this[y, x] = hundredsDigit - 5
27-
cache[Configuration(Coordinates(x, y), 1)] = this[y, x]
26+
this[x, y] = hundredsDigit - 5
27+
cache[Configuration(Coordinates(x, y), 1)] = this[x, y]
2828
}.last()
2929
}
3030

@@ -55,9 +55,9 @@ class PowerCellGrid(serialNumber: Int) : Grid<Int>(300, 300, -1000) {
5555
} else {
5656
val total = cache[Configuration(coordinates, squareSize - 1)]?.let { cached ->
5757
val additionalColumnTotal =
58-
(0..<squareSize).sumOf { this[coordinates.y + it, coordinates.x + squareSize - 1] }
58+
(0..<squareSize).sumOf { this[coordinates.x + squareSize - 1, coordinates.y + it] }
5959
val additionalRowTotal =
60-
(0..<squareSize - 1).sumOf { this[coordinates.y + squareSize - 1, coordinates.x + it] }
60+
(0..<squareSize - 1).sumOf { this[coordinates.x + it, coordinates.y + squareSize - 1] }
6161
cached + additionalColumnTotal + additionalRowTotal
6262
} ?: sumOfSquare(coordinates, squareSize)
6363
cache[config] = total
@@ -77,7 +77,7 @@ class PowerCellGrid(serialNumber: Int) : Grid<Int>(300, 300, -1000) {
7777

7878
private fun sumOfSquare(coordinates: Coordinates, squareSize: Int): Int = (0..<squareSize).sumOf { r ->
7979
(0..<squareSize).sumOf { c ->
80-
this[coordinates.y + r, coordinates.x + c]
80+
this[coordinates.x + c, coordinates.y + r]
8181
}
8282
}
8383

src/main/kotlin/de/ronny_h/aoc/year2024/day04/CeresSearch.kt

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,23 @@ class XMasGrid(input: List<String>) : Grid<Char>(input, ' ') {
2424

2525
fun searchForMASCross() = forEachIndex(::searchForMASCrossAt).sum()
2626

27-
private fun searchForXMASAt(row: Int, col: Int): Int {
27+
private fun searchForXMASAt(x: Int, y: Int): Int {
2828
var sum = 0
29-
sum += searchForXMAS(row, col, { a, _ -> a }, { a, b -> a + b }) //
30-
sum += searchForXMAS(row, col, { a, _ -> a }, { a, b -> a - b }) //
31-
sum += searchForXMAS(row, col, { a, b -> a + b }, { a, _ -> a }) //
32-
sum += searchForXMAS(row, col, { a, b -> a - b }, { a, _ -> a }) //
33-
sum += searchForXMAS(row, col, { a, b -> a + b }, { a, b -> a + b }) //
34-
sum += searchForXMAS(row, col, { a, b -> a + b }, { a, b -> a - b }) //
35-
sum += searchForXMAS(row, col, { a, b -> a - b }, { a, b -> a - b }) //
36-
sum += searchForXMAS(row, col, { a, b -> a - b }, { a, b -> a + b }) //
29+
sum += searchForXMAS(x, y, { a, b -> a + b }) { a, _ -> a } //
30+
sum += searchForXMAS(x, y, { a, b -> a - b }) { a, _ -> a } //
31+
sum += searchForXMAS(x, y, { a, _ -> a }) { a, b -> a + b } //
32+
sum += searchForXMAS(x, y, { a, _ -> a }) { a, b -> a - b } //
33+
sum += searchForXMAS(x, y, { a, b -> a + b }) { a, b -> a + b } //
34+
sum += searchForXMAS(x, y, { a, b -> a - b }) { a, b -> a + b } //
35+
sum += searchForXMAS(x, y, { a, b -> a - b }) { a, b -> a - b } //
36+
sum += searchForXMAS(x, y, { a, b -> a + b }) { a, b -> a - b } //
3737
return sum
3838
}
3939

40-
private fun searchForXMAS(row: Int, col: Int, rowOp: (Int, Int) -> Int, colOp: (Int, Int) -> Int): Int {
40+
private fun searchForXMAS(x: Int, y: Int, xOp: (Int, Int) -> Int, yOp: (Int, Int) -> Int): Int {
4141
var matchIndex = 0
4242
for (index in word.indices) {
43-
if (get(rowOp(row, index), colOp(col, index)) == word[matchIndex]) {
43+
if (get(xOp(x, index), yOp(y, index)) == word[matchIndex]) {
4444
if (matchIndex == word.lastIndex) {
4545
return 1
4646
}
@@ -52,24 +52,24 @@ class XMasGrid(input: List<String>) : Grid<Char>(input, ' ') {
5252
return 0
5353
}
5454

55-
private fun searchForMASCrossAt(row: Int, col: Int): Int {
56-
if (get(row, col) != 'A') {
55+
private fun searchForMASCrossAt(x: Int, y: Int): Int {
56+
if (get(x, y) != 'A') {
5757
return 0
5858
}
59-
if ((mainDiagIsMAS(row, col) || mainDiagIsSAM(row, col)) &&
60-
(secDiagIsMAS(row, col) || secDiagIsSAM(row, col))
59+
if ((mainDiagIsMAS(x, y) || mainDiagIsSAM(x, y)) &&
60+
(secDiagIsMAS(x, y) || secDiagIsSAM(x, y))
6161
) {
6262
return 1
6363
}
6464
return 0
6565
}
6666

67-
private fun mainDiagIsMAS(row: Int, col: Int) = get(row - 1, col - 1) == 'M' && get(row + 1, col + 1) == 'S'
67+
private fun mainDiagIsMAS(x: Int, y: Int) = get(x - 1, y - 1) == 'M' && get(x + 1, y + 1) == 'S'
6868

69-
private fun mainDiagIsSAM(row: Int, col: Int) = get(row - 1, col - 1) == 'S' && get(row + 1, col + 1) == 'M'
69+
private fun mainDiagIsSAM(x: Int, y: Int) = get(x - 1, y - 1) == 'S' && get(x + 1, y + 1) == 'M'
7070

71-
private fun secDiagIsMAS(row: Int, col: Int) = get(row - 1, col + 1) == 'M' && get(row + 1, col - 1) == 'S'
71+
private fun secDiagIsMAS(x: Int, y: Int) = get(x + 1, y - 1) == 'M' && get(x - 1, y + 1) == 'S'
7272

73-
private fun secDiagIsSAM(row: Int, col: Int) = get(row - 1, col + 1) == 'S' && get(row + 1, col - 1) == 'M'
73+
private fun secDiagIsSAM(x: Int, y: Int) = get(x + 1, y - 1) == 'S' && get(x - 1, y + 1) == 'M'
7474

7575
}

src/main/kotlin/de/ronny_h/aoc/year2024/day06/GuardGallivant.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ private class Lab(input: List<String>) : Grid<Char>(input, ' ') {
6060

6161
@OptIn(ExperimentalCoroutinesApi::class)
6262
fun freePositions(scope: CoroutineScope, bufferSize: Int) = scope.produce(capacity = bufferSize) {
63-
forEachElement { row, col, char ->
64-
if (char == free) Coordinates(col, row) else null
63+
forEachElement { x, y, char ->
64+
if (char == free) Coordinates(x, y) else null
6565
}
6666
.filterNotNull()
6767
.forEach {

src/main/kotlin/de/ronny_h/aoc/year2024/day08/ResonantCollinearity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ private class CityMap(input: List<String>) : Grid<Char>(input, '.') {
2727
private val rowIndices = input.indices
2828

2929
private val antennas: Map<Char, List<Coordinates>> = buildMap<Char, MutableList<Coordinates>> {
30-
forEachElement { row, col, char ->
30+
forEachElement { x, y, char ->
3131
if (char != nullElement) {
32-
getOrPut(char, ::mutableListOf).add(Coordinates(col, row))
32+
getOrPut(char, ::mutableListOf).add(Coordinates(x, y))
3333
}
3434
}.last()
3535
}

src/main/kotlin/de/ronny_h/aoc/year2024/day10/HoofIt.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ private class TopographicMap(input: List<String>) : Grid<Int>(input, Int.MIN_VAL
2121

2222
override fun Char.toElementType() = if (isDigit()) digitToInt() else nullElement
2323

24-
private fun heights(): Sequence<Pair<Coordinates, Int>> = forEachElement { row, col, height ->
25-
Coordinates(col, row) to height
24+
private fun heights(): Sequence<Pair<Coordinates, Int>> = forEachElement { x, y, height ->
25+
Coordinates(x, y) to height
2626
}
2727

2828
private fun heightAt(coordinates: Coordinates) = getAt(coordinates)

src/main/kotlin/de/ronny_h/aoc/year2024/day15/WarehouseWoes.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ abstract class Warehouse(input: List<String>) : Grid<Char>(input, '#') {
6666
}
6767

6868
// GPS = Goods Positioning System
69-
fun sumGPSCoordinates(): Int = forEachElement { row, col, element ->
69+
fun sumGPSCoordinates(): Int = forEachElement { x, y, element ->
7070
if (element == leftGoodsChar) {
71-
100 * row + col
71+
100 * y + x
7272
} else {
7373
0
7474
}

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

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ class GridTest : StringSpec() {
3838
"charAt returns the input values from the right indices" {
3939
val grid = SimpleCharGrid(listOf("12", "34"))
4040
grid[0, 0] shouldBe '1'
41-
grid[0, 1] shouldBe '2'
42-
grid[1, 0] shouldBe '3'
41+
grid[1, 0] shouldBe '2'
42+
grid[0, 1] shouldBe '3'
4343
grid[1, 1] shouldBe '4'
4444
}
4545

@@ -48,52 +48,52 @@ class GridTest : StringSpec() {
4848
override fun Char.toElementType() = digitToInt()
4949
}
5050
grid[0, 0] shouldBe 1
51-
grid[0, 1] shouldBe 2
52-
grid[1, 0] shouldBe 3
51+
grid[1, 0] shouldBe 2
52+
grid[0, 1] shouldBe 3
5353
grid[1, 1] shouldBe 4
5454
}
5555

5656
"charAt with indices returns the same as charAt with Coordinates" {
5757
val grid = SimpleCharGrid(listOf("12", "34"))
5858
grid[0, 0] shouldBe grid.getAt(Coordinates(0, 0))
59-
grid[0, 1] shouldBe grid.getAt(Coordinates(1, 0))
60-
grid[1, 0] shouldBe grid.getAt(Coordinates(0, 1))
59+
grid[0, 1] shouldBe grid.getAt(Coordinates(0, 1))
60+
grid[1, 0] shouldBe grid.getAt(Coordinates(1, 0))
6161
grid[1, 1] shouldBe grid.getAt(Coordinates(1, 1))
6262
}
6363

6464
"charAt with index out of the input values returns the nullElement of a Char Grid" {
6565
val grid = SimpleCharGrid(listOf("12", "34"), ' ')
66-
grid[-1, 0] shouldBe ' '
67-
grid[0, 2] shouldBe ' '
68-
grid[1, -1] shouldBe ' '
66+
grid[0, -1] shouldBe ' '
67+
grid[2, 0] shouldBe ' '
68+
grid[-1, 1] shouldBe ' '
6969
grid[2, 2] shouldBe ' '
7070
}
7171

7272
"charAt with index out of the input values returns the nullElement of an Int Grid" {
7373
val grid = object : Grid<Int>(listOf("12", "34"), Int.MIN_VALUE) {
7474
override fun Char.toElementType() = digitToInt()
7575
}
76-
grid[-1, 0] shouldBe Int.MIN_VALUE
77-
grid[0, 2] shouldBe Int.MIN_VALUE
78-
grid[1, -1] shouldBe Int.MIN_VALUE
76+
grid[0, -1] shouldBe Int.MIN_VALUE
77+
grid[2, 0] shouldBe Int.MIN_VALUE
78+
grid[-1, 1] shouldBe Int.MIN_VALUE
7979
grid[2, 2] shouldBe Int.MIN_VALUE
8080
}
8181

8282
"setAt sets the element at the given coordinates" {
8383
val grid = SimpleCharGrid(listOf("12", "34"))
8484
grid.setAt(Coordinates(0, 1), '5')
8585
grid[0, 0] shouldBe '1'
86-
grid[0, 1] shouldBe '2'
87-
grid[1, 0] shouldBe '5'
86+
grid[1, 0] shouldBe '2'
87+
grid[0, 1] shouldBe '5'
8888
grid[1, 1] shouldBe '4'
8989
}
9090

9191
"set with array access sets the element at the given coordinates" {
9292
val grid = SimpleCharGrid(listOf("12", "34"))
93-
grid[1, 0] = '5'
93+
grid[0, 1] = '5'
9494
grid[0, 0] shouldBe '1'
95-
grid[0, 1] shouldBe '2'
96-
grid[1, 0] shouldBe '5'
95+
grid[1, 0] shouldBe '2'
96+
grid[0, 1] shouldBe '5'
9797
grid[1, 1] shouldBe '4'
9898
}
9999

@@ -104,24 +104,24 @@ class GridTest : StringSpec() {
104104
90AB
105105
CDEF
106106
""".asList()
107-
SimpleCharGrid(input).subGridAt(1, 1, 2) shouldBe listOf(
107+
SimpleCharGrid(input).subGridAt(1, 1, width = 2) shouldBe listOf(
108108
listOf('6', '7'),
109109
listOf('0', 'A'),
110110
)
111111
}
112112

113113
"forEachIndex calls the provided function on each element in the expected order" {
114114
val grid = SimpleCharGrid(listOf("12", "34"))
115-
val chars = grid.forEachIndex { row, column ->
116-
grid[row, column]
115+
val chars = grid.forEachIndex { x, y ->
116+
grid[x, y]
117117
}.toList()
118118
chars shouldBe listOf('1', '2', '3', '4')
119119
}
120120

121121
"forEachElement calls the provided function on each element in the expected order" {
122122
val grid = SimpleCharGrid(listOf("12", "34"))
123-
val strings = grid.forEachElement { row, column, char ->
124-
"$row,$column:$char"
123+
val strings = grid.forEachElement { x, y, char ->
124+
"$y,$x:$char"
125125
}.toList()
126126
strings shouldBe
127127
listOf(

src/test/kotlin/de/ronny_h/aoc/year2018/day11/ChronalChargeTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class ChronalChargeTest : StringSpec({
1414
row(217, 196, 39, 0),
1515
row(101, 153, 71, 4),
1616
) { x, y, serialNumber, powerLevel ->
17-
PowerCellGrid(serialNumber)[y, x] shouldBe powerLevel
17+
PowerCellGrid(serialNumber)[x, y] shouldBe powerLevel
1818
}
1919
}
2020

0 commit comments

Comments
 (0)