day(06): solve

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2024-12-06 12:35:30 +01:00
parent 73fd14df89
commit 965f2ea9f5
Signed by: mfocko
SSH key fingerprint: SHA256:icm0fIOSJUpy5+1x23sfr+hLtF9UhY8VpMC7H4WFJP8
2 changed files with 105 additions and 0 deletions

10
inputs/day06/sample.txt Normal file
View file

@ -0,0 +1,10 @@
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...

95
src/Day06.kt Normal file
View file

@ -0,0 +1,95 @@
class Day06(
inputType: String,
) : Day<Int, Int>() {
private val map: Array<CharArray> = readInput(6, inputType).map { it.toCharArray() }.toTypedArray()
private val initialPosition: Pair<Int, Int> =
let {
for (row in map.withIndex()) {
for (cell in row.value.withIndex()) {
if (cell.value == '^') {
return@let cell.index to row.index
}
}
}
error("there's always at least one guard")
}
private val route: Set<Pair<Int, Int>> =
let {
var pos = initialPosition
var direction = 0 to -1
val seen = mutableSetOf<Pair<Int, Int>>()
while (inBounds(pos)) {
seen.add(pos)
var next = move(pos, direction)
while (!canMoveTo(next)) {
direction = rotate(direction)
next = move(pos, direction)
}
pos = next
}
return@let seen
}
override fun precompute() {
// no-op
}
private fun inBounds(p: Pair<Int, Int>): Boolean =
p.let { (x, y) ->
y >= 0 && y < map.size && x >= 0 && x < map[y].size
}
private fun move(
p: Pair<Int, Int>,
d: Pair<Int, Int>,
): Pair<Int, Int> {
val (x, y) = p
val (dx, dy) = d
return x + dx to y + dy
}
private fun canMoveTo(p: Pair<Int, Int>): Boolean =
p.let { (x, y) ->
!inBounds(p) || map[y][x] != '#'
}
private fun rotate(d: Pair<Int, Int>): Pair<Int, Int> =
d.let { (dx, dy) ->
-dy to dx
}
override fun part1(): Int = route.size
override fun part2(): Int =
route.filter { it != initialPosition }.count { o ->
var pos = initialPosition
var direction = 0 to -1
val visited = mutableSetOf<Pair<Pair<Int, Int>, Pair<Int, Int>>>()
while (inBounds(pos) && !visited.contains(direction to pos)) {
visited.add(direction to pos)
var next = move(pos, direction)
while (next == o || !canMoveTo(next)) {
direction = rotate(direction)
next = move(pos, direction)
}
pos = next
}
inBounds(pos)
}
}
fun main() {
Day06("sample").test(41, 6)
Day06("input").run()
}