diff --git a/inputs/day06/sample.txt b/inputs/day06/sample.txt new file mode 100644 index 0000000..b60e466 --- /dev/null +++ b/inputs/day06/sample.txt @@ -0,0 +1,10 @@ +....#..... +.........# +.......... +..#....... +.......#.. +.......... +.#..^..... +........#. +#......... +......#... \ No newline at end of file diff --git a/src/Day06.kt b/src/Day06.kt new file mode 100644 index 0000000..1f270b2 --- /dev/null +++ b/src/Day06.kt @@ -0,0 +1,95 @@ +class Day06( + inputType: String, +) : Day() { + private val map: Array = readInput(6, inputType).map { it.toCharArray() }.toTypedArray() + + private val initialPosition: Pair = + 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> = + let { + var pos = initialPosition + var direction = 0 to -1 + + val seen = mutableSetOf>() + 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): Boolean = + p.let { (x, y) -> + y >= 0 && y < map.size && x >= 0 && x < map[y].size + } + + private fun move( + p: Pair, + d: Pair, + ): Pair { + val (x, y) = p + val (dx, dy) = d + return x + dx to y + dy + } + + private fun canMoveTo(p: Pair): Boolean = + p.let { (x, y) -> + !inBounds(p) || map[y][x] != '#' + } + + private fun rotate(d: Pair): Pair = + 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>>() + 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() +}