Skip to content

Commit 5cca20f

Browse files
committed
Refactor the Grid class to be able to pass a list of special coordinates
Pass the nullElement and overrideElement as constructor parameters. Otherwise they don't have the value overridden in sub-classes while constructor execution. Kotlin initializes the super class first (including its properties and constructors) and then the sub class(es).
1 parent a934924 commit 5cca20f

File tree

9 files changed

+38
-32
lines changed

9 files changed

+38
-32
lines changed

src/main/kotlin/Day04.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,9 @@ fun main() {
4747
printAndCheck(input, ::part2, 1933)
4848
}
4949

50-
class XMasGrid(input: List<String>) : Grid<Char>(input) {
50+
class XMasGrid(input: List<String>) : Grid<Char>(input, ' ') {
5151

5252
private val word = "XMAS".toCharArray()
53-
override val nullElement = ' '
5453
override fun Char.toElementType() = this
5554

5655
fun searchForXMAS() = forEachIndex(::searchForXMASAt).sum()

src/main/kotlin/Day06.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,12 @@ suspend fun main() {
8181
printAndCheck(input, ::part2, 1480)
8282
}
8383

84-
private class Lab(input: List<String>) : Grid<Char>(input) {
84+
private class Lab(input: List<String>) : Grid<Char>(input, ' ') {
8585

8686
private val guard = '^'
8787
private val obstruction = '#'
8888
private val free = '.'
89-
private val offMap = ' '
90-
override val nullElement = offMap
89+
private val offMap = nullElement
9190
override fun Char.toElementType() = this
9291

9392
private fun findTheGuard(): Coordinates = forEachElement { row, col, element ->

src/main/kotlin/Day08.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ fun main() {
5252
printAndCheck(input, ::part2, 809)
5353
}
5454

55-
private class CityMap(input: List<String>) : Grid<Char>(input) {
55+
private class CityMap(input: List<String>) : Grid<Char>(input, '.') {
5656

57-
override val nullElement = '.'
5857
override fun Char.toElementType() = this
5958

6059
private val colIndices = input[0].indices

src/main/kotlin/Day10.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,9 @@ fun main() {
5151
printAndCheck(input, ::part2, 1960)
5252
}
5353

54-
private class TopographicMap(input: List<String>) : Grid<Int>(input) {
54+
private class TopographicMap(input: List<String>) : Grid<Int>(input, Int.MIN_VALUE) {
5555

56-
override val nullElement = Int.MIN_VALUE
57-
override fun Char.toElementType() = if (isDigit()) digitToInt() else Int.MIN_VALUE
56+
override fun Char.toElementType() = if (isDigit()) digitToInt() else nullElement
5857

5958
private fun heights(): Sequence<Pair<Coordinates, Int>> = forEachElement { row, col, height ->
6059
Coordinates(row, col) to height

src/main/kotlin/Day12.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,7 @@ fun main() {
9898

9999
private data class Region(val area: Int, val perimeter: Int, val numberOfSides: Int)
100100

101-
private class Farm(input: List<String>) : Grid<Char>(input) {
102-
private val offMap = ' '
103-
override val nullElement = offMap
101+
private class Farm(input: List<String>) : Grid<Char>(input, ' ') {
104102
override fun Char.toElementType() = this
105103

106104
val assigned = mutableSetOf<Coordinates>()

src/main/kotlin/Day15_part1.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,11 @@ fun List<String>.toDay15Movements(): List<Direction> = takeLastWhile { it.isNotB
5555
}
5656

5757

58-
abstract class Warehouse(input: List<String>) : Grid<Char>(input) {
59-
protected val wall = '#'
58+
abstract class Warehouse(input: List<String>) : Grid<Char>(input, '#') {
59+
protected val wall = nullElement
6060
protected val robot = '@'
6161
protected val free = '.'
6262

63-
override val nullElement = wall
6463
override fun Char.toElementType(): Char = this
6564

6665
protected abstract val leftGoodsChar: Char

src/main/kotlin/Day16.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ fun main() {
112112
printAndCheck(input, ::part2, 504)
113113
}
114114

115-
private class ReindeerMaze(input: List<String>) : Grid<Char>(input) {
116-
private val wall = '#'
117-
override val nullElement = wall
115+
private class ReindeerMaze(input: List<String>) : Grid<Char>(input, '#') {
116+
private val wall = nullElement
118117
override fun Char.toElementType() = this
119118

120119
data class Node(val direction: Direction, val position: Coordinates) {

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

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

3-
abstract class Grid<T>(input: List<String>) {
4-
val height = input.size
5-
val width = input[0].length
3+
import kotlin.collections.MutableList
4+
5+
/**
6+
* @param nullElement The initial element within the grid
7+
* @param overrideElement Used for out of bound positions. Defaults to `nullElement`
8+
*/
9+
abstract class Grid<T>(
10+
val height: Int,
11+
val width: Int,
12+
protected val nullElement: T,
13+
private val overrideElement: T = nullElement,
14+
) {
15+
16+
private val grid: MutableList<MutableList<T>> = MutableList(height) { MutableList(width) { nullElement } }
617

7-
abstract val nullElement: T
818
abstract fun Char.toElementType(): T
919

10-
private val grid = MutableList(height) { MutableList(width) { nullElement } }
20+
constructor(height: Int, width: Int, nullElement: T, overrideElement: T = nullElement, overrides: List<Coordinates> = emptyList()) : this(height, width, nullElement, overrideElement) {
21+
overrides.forEach {
22+
grid[it.row][it.col] = overrideElement
23+
}
24+
}
1125

12-
init {
26+
constructor(input: List<String>, nullElement: T, overrideElement: T = nullElement) : this(input.size, input[0].length, nullElement, overrideElement, emptyList()){
1327
input.forEachIndexed { row, line ->
1428
line.forEachIndexed { col, char -> grid[row][col] = char.toElementType() }
1529
}
1630
}
1731

1832
operator fun get(row: Int, col: Int): T {
19-
return grid.getOrNull(row)?.getOrNull(col) ?: nullElement
33+
return grid
34+
.getOrNull(row)
35+
?.getOrNull(col)
36+
?: overrideElement
2037
}
2138

2239
fun getAt(position: Coordinates) = get(position.row, position.col)

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import io.kotlintest.specs.StringSpec
77

88
class GridTest : StringSpec() {
99

10-
private fun simpleCharGridOf(input: List<String>) = object : Grid<Char>(input) {
11-
override val nullElement = ' '
10+
private fun simpleCharGridOf(input: List<String>) = object : Grid<Char>(input, ' ') {
1211
override fun Char.toElementType() = this
1312
}
1413

@@ -36,8 +35,7 @@ class GridTest : StringSpec() {
3635
}
3736

3837
"toElementType converts the input values" {
39-
val grid = object : Grid<Int>(listOf("12", "34")) {
40-
override val nullElement = Int.MIN_VALUE
38+
val grid = object : Grid<Int>(listOf("12", "34"), Int.MIN_VALUE) {
4139
override fun Char.toElementType() = digitToInt()
4240
}
4341
grid[0, 0] shouldBe 1
@@ -63,8 +61,7 @@ class GridTest : StringSpec() {
6361
}
6462

6563
"charAt with index out of the input values returns the nullElement of an Int Grid" {
66-
val grid = object : Grid<Int>(listOf("12", "34")) {
67-
override val nullElement = Int.MIN_VALUE
64+
val grid = object : Grid<Int>(listOf("12", "34"), Int.MIN_VALUE) {
6865
override fun Char.toElementType() = digitToInt()
6966
}
7067
grid[-1, 0] shouldBe Int.MIN_VALUE

0 commit comments

Comments
 (0)