Skip to content

Commit 80b9bcc

Browse files
committed
day 15 solution, part 2
1 parent b605d91 commit 80b9bcc

File tree

1 file changed

+69
-11
lines changed
  • day15/src/main/kotlin/org/adventofcode

1 file changed

+69
-11
lines changed

day15/src/main/kotlin/org/adventofcode/App.kt

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,39 +18,83 @@ interface Grid {
1818
val width: Int;
1919
val height: Int;
2020
val lastPoint: Point;
21+
fun isEmpty(): Boolean;
22+
fun isNotEmpty(): Boolean;
2123
operator fun contains(p: Point): Boolean;
2224
operator fun get(p: Point): Int?;
2325
}
2426

25-
data class ImmutableGrid(val data: List<List<Int>>) : Grid {
26-
override val height: Int by lazy { data.size }
27-
override val width: Int by lazy { if (data.isNotEmpty()) data[0].size else 0 }
27+
abstract class BaseImmutableGrid : Grid {
2828
override val lastPoint: Point by lazy { Point(width - 1, height -1 ) }
2929

30+
override fun isEmpty(): Boolean {
31+
return width == 0 && height == 0
32+
}
33+
34+
override fun isNotEmpty(): Boolean {
35+
return !isEmpty()
36+
}
37+
3038
override operator fun contains(p: Point): Boolean {
3139
val insideRowRange = p.row in 0 until height
3240
val insideColRange = p.col in 0 until width
3341
return insideRowRange && insideColRange
3442
}
43+
}
44+
45+
data class ImmutableGrid(val data: List<List<Int>>) : BaseImmutableGrid() {
46+
override val height: Int by lazy { data.size }
47+
override val width: Int by lazy { if (data.isNotEmpty()) data[0].size else 0 }
3548

3649
override fun get(p: Point): Int? {
3750
return data[p.row][p.col]
3851
}
3952
}
4053

41-
fun ImmutableGrid.prettyPrint(withPath: Path? = null) {
54+
fun Grid.prettyPrint(withPath: Path? = null) {
4255
val pointset = withPath?.let { it.toSet() } ?: setOf()
4356
val padding = 2 + (withPath?.let { 4 } ?: 0)
44-
this.data.forEachIndexed { rowIdx, row ->
45-
val s = row.mapIndexed { colIdx, value ->
57+
(0 until height).forEach { rowIdx ->
58+
val s = (0 until width).map { colIdx ->
4659
val point = Point(colIdx, rowIdx)
60+
val value = this[point]
4761
val attr = withPath?.let { if (point in pointset) "{*}" else null }
4862
"$value${attr?.let { it } ?: ""}".padEnd(padding)
4963
}
5064
println(s.joinToString(""))
5165
}
5266
}
5367

68+
data class TiledGrid(
69+
val tile: Grid,
70+
val widthScale: Int = 1,
71+
val heightScale: Int = 1
72+
) : BaseImmutableGrid() {
73+
constructor(
74+
data: List<List<Int>>,
75+
widthScale: Int = 1,
76+
heightScale: Int = 1,
77+
) : this(ImmutableGrid(data), widthScale, heightScale)
78+
79+
override val height: Int by lazy { tile.height * heightScale }
80+
override val width: Int by lazy { tile.width * widthScale }
81+
82+
override fun get(p: Point): Int? {
83+
if (p !in this) {
84+
return null
85+
}
86+
87+
val colTileIdx = (p.col / tile.width)
88+
val rowTileIdx = (p.row / tile.height)
89+
val inColTileIdx = p.col % tile.width
90+
val inRowTileIdx = p.row % tile.height
91+
val inTilePoint = Point(inColTileIdx, inRowTileIdx)
92+
val inTileValue = tile[inTilePoint] ?: throw error("Invalid point in tile $inTilePoint")
93+
val baseValue = inTileValue - 1 + colTileIdx + rowTileIdx
94+
return (baseValue % 9) + 1
95+
}
96+
}
97+
5498
data class TraversalEntry(val parent: Point? = null, val cost: Double = 0.0)
5599

56100
object PathFinder {
@@ -96,15 +140,29 @@ object PathFinder {
96140

97141
}
98142

99-
fun main() {
100-
val data = File("day15/src/main/resources/puzzleInput.txt")
101-
.readLines()
102-
.map { it.split("").drop(1).dropLast(1).map(String::toInt) }
103-
143+
fun runSolutionPart1(data: List<List<Int>>) {
144+
println("Day 15 Solution: Part 1\n\n")
104145
val grid = ImmutableGrid(data)
105146
val path = PathFinder.findShortestPath(grid)
106147
grid.prettyPrint(path)
148+
val cost = path.drop(1).sumOf { grid[it] ?: 0 }
107149
println()
150+
println("total cost: $cost")
151+
}
152+
153+
fun runSolutionPart2(data: List<List<Int>>) {
154+
println("Day 15 Solution: Part 2\n")
155+
val grid = TiledGrid(data, widthScale = 5, heightScale = 5)
156+
val path = PathFinder.findShortestPath(grid)
108157
val cost = path.drop(1).sumOf { grid[it] ?: 0 }
109158
println("total cost: $cost")
110159
}
160+
161+
fun main() {
162+
val data = File("day15/src/main/resources/puzzleInput.txt")
163+
.readLines()
164+
.map { it.split("").drop(1).dropLast(1).map(String::toInt) }
165+
166+
runSolutionPart1(data)
167+
// runSolutionPart2(data)
168+
}

0 commit comments

Comments
 (0)