Skip to content

Commit 118f296

Browse files
committed
Solution Day 15, part one
1 parent b99df0f commit 118f296

File tree

4 files changed

+119
-1
lines changed

4 files changed

+119
-1
lines changed

src/main/kotlin/Day14.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ fun main() {
123123

124124
fun part2(input: List<String>) = iterateUntilSymmetrical(input.parseRobots(), 101, 103)
125125

126-
printAndCheck(input, ::part2, 91649162)
126+
printAndCheck(input, ::part2, 6512)
127127
}
128128

129129
data class Robot(val px: Int, val py: Int, val vx: Int, val vy: Int)

src/main/kotlin/Day15.kt

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import de.ronny_h.extensions.Coordinates
2+
import de.ronny_h.extensions.Direction
3+
import de.ronny_h.extensions.Grid
4+
5+
fun main() {
6+
val day = "Day15"
7+
8+
println("$day part 1")
9+
10+
fun part1(input: List<String>): Int {
11+
val warehouse = Warehouse(input.takeWhile { it.isNotBlank() })
12+
warehouse.printGrid()
13+
14+
val movements = input
15+
.takeLastWhile { it.isNotBlank() }
16+
.joinToString(separator = "")
17+
.map {
18+
when (it) {
19+
'^' -> Direction.NORTH
20+
'>' -> Direction.EAST
21+
'v' -> Direction.SOUTH
22+
'<' -> Direction.WEST
23+
else -> error("Unexpected direction Char: $it")
24+
}
25+
}
26+
27+
warehouse.moveRobot(movements)
28+
warehouse.printGrid()
29+
30+
return warehouse.sumGPSCoordinates()
31+
}
32+
33+
printAndCheck(
34+
"""
35+
########
36+
#..O.O.#
37+
##@.O..#
38+
#...O..#
39+
#.#.O..#
40+
#...O..#
41+
#......#
42+
########
43+
44+
<^^>>>vv<v>>v<<
45+
""".trimIndent().lines(),
46+
::part1, 2028
47+
)
48+
49+
val testInput = readInput("${day}_test")
50+
printAndCheck(testInput, ::part1, 10092)
51+
52+
val input = readInput(day)
53+
printAndCheck(input, ::part1, 1463715)
54+
}
55+
56+
private class Warehouse(input: List<String>) : Grid<Char>(input) {
57+
private val wall = '#'
58+
private val robot = '@'
59+
private val free = '.'
60+
private val goods = 'O'
61+
62+
override val nullElement = wall
63+
override fun Char.toElementType(): Char = this
64+
65+
fun moveRobot(movements: List<Direction>) {
66+
movements.fold(findTheRobot()) { position, direction ->
67+
if (tryToMove(position, direction, robot)) {
68+
position + direction
69+
} else {
70+
position
71+
}
72+
}
73+
}
74+
75+
private fun tryToMove(from: Coordinates, direction: Direction, thing: Char): Boolean {
76+
val target = from + direction
77+
if (getAt(target) == free) {
78+
setAt(target, thing)
79+
setAt(from, free)
80+
return true
81+
}
82+
if (getAt(target) == wall) {
83+
return false
84+
}
85+
check(getAt(target) == goods)
86+
if (tryToMove(target, direction, goods)) {
87+
setAt(target, thing)
88+
setAt(from, free)
89+
return true
90+
}
91+
return false
92+
}
93+
94+
private fun findTheRobot(): Coordinates = forEachElement { row, col, element ->
95+
if (element == robot) Coordinates(row, col) else null
96+
}.filterNotNull().first()
97+
98+
fun sumGPSCoordinates(): Int = forEachElement { row, col, element ->
99+
if (element == goods) {
100+
100 * row + col
101+
} else {
102+
0
103+
}
104+
}.sum()
105+
106+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ abstract class Grid<T>(input: List<String>) {
2020
}
2121

2222
fun getAt(position: Coordinates) = get(position.row, position.col)
23+
fun setAt(position: Coordinates, element: T) {
24+
grid[position.row][position.col] = element
25+
}
2326

2427
fun <R> forEachIndex(action: (row: Int, col: Int) -> R): Sequence<R> = sequence {
2528
for (row in grid.indices) {

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ class GridTest : StringSpec() {
7373
grid[2, 2] shouldBe Int.MIN_VALUE
7474
}
7575

76+
"setAt sets the element at the given coordinates" {
77+
val grid = simpleCharGridOf(listOf("12", "34"))
78+
grid.setAt(Coordinates(1, 0), '5')
79+
grid[0, 0] shouldBe '1'
80+
grid[0, 1] shouldBe '2'
81+
grid[1, 0] shouldBe '5'
82+
grid[1, 1] shouldBe '4'
83+
}
84+
7685
"forEachIndex calls the provided function on each element in the expected order" {
7786
val grid = simpleCharGridOf(listOf("12", "34"))
7887
val chars = grid.forEachIndex { row, column ->

0 commit comments

Comments
 (0)