From acf453d45e0c1c866468738dc328661aaa902554 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Wed, 15 Dec 2021 10:56:32 +0100 Subject: [PATCH] day(15): add solution Signed-off-by: Matej Focko --- src/year2021/day15/Day15.kt | 126 ++++++++++++++++++++++++++++++++++ src/year2021/day15/sample.txt | 10 +++ 2 files changed, 136 insertions(+) create mode 100644 src/year2021/day15/Day15.kt create mode 100644 src/year2021/day15/sample.txt diff --git a/src/year2021/day15/Day15.kt b/src/year2021/day15/Day15.kt new file mode 100644 index 0000000..bf3cef4 --- /dev/null +++ b/src/year2021/day15/Day15.kt @@ -0,0 +1,126 @@ +package year2021.day15 + +import readInput +import java.util.* + +fun validAdjacentIndices(input: List>, y0: Int, x0: Int): Iterable> = + (y0 - 1..y0 + 1) + .flatMap { y -> (x0 - 1..x0 + 1).map { x -> Pair(y, x) } } + .filter { (y, x) -> + (y != y0 || x != x0) && (y == y0 || x == x0) && (y >= 0 && y < input.size) && (x >= 0 && x < input[y].size) + } + +fun validAdjacentIndicesExtended(input: List>, y0: Int, x0: Int): Iterable> = + (y0 - 1..y0 + 1) + .flatMap { y -> (x0 - 1..x0 + 1).map { x -> Pair(y, x) } } + .filter { (y, x) -> + (y != y0 || x != x0) && (y == y0 || x == x0) && (y >= 0 && y < 5 * input.size) && (x >= 0 && x < 5 * input[0].size) + } + +data class Coordinate(val y: Int, val x: Int) + +fun part1(input: List>): Int { + val final = Coordinate(input.size - 1, input.last().size - 1) + + val queue = PriorityQueue>() { a, b -> + a.first - b.first + } + val distances = mutableMapOf() + val processed = mutableSetOf() + + queue.add(Pair(0, Coordinate(0, 0))) + distances[Coordinate(0, 0)] = 0 + for (y in input.indices) { + for (x in input[y].indices) { + queue.add(Pair(Int.MAX_VALUE, Coordinate(y, x))) + } + } + + while (queue.isNotEmpty()) { + val (distance, coordinate) = queue.remove()!! + if (processed.contains(coordinate)) { + continue + } + processed.add(coordinate) + + if (coordinate == final) { + return distance + } + + for ((y, x) in validAdjacentIndices(input, coordinate.y, coordinate.x)) { + val neighbour = Coordinate(y, x) + val alternative = distance + input[y][x] + + if (alternative < (distances[neighbour] ?: Int.MAX_VALUE)) { + distances[neighbour] = alternative + queue.add(Pair(alternative, neighbour)) + } + } + } + return Int.MAX_VALUE +} + +fun getDistance(input: List>, y: Int, x: Int): Int { + val riskLevel = input[y % input.size][x % input[0].size] + val added = y / input.size + x / input[0].size + + if (riskLevel + added > 9) { + return riskLevel + added - 9 + } + + return riskLevel + added +} + +fun part2(input: List>): Int { + val final = Coordinate(5 * input.size - 1, 5 * input.last().size - 1) + + val queue = PriorityQueue>() { a, b -> + a.first - b.first + } + val distances = mutableMapOf() + val processed = mutableSetOf() + + queue.add(Pair(0, Coordinate(0, 0))) + distances[Coordinate(0, 0)] = 0 + for (y in input.indices) { + for (x in input[y].indices) { + for (i in 0 until 5) { + queue.add(Pair(Int.MAX_VALUE, Coordinate(i * y, i * x))) + } + } + } + + while (queue.isNotEmpty()) { + val (distance, coordinate) = queue.remove()!! + if (processed.contains(coordinate)) { + continue + } + processed.add(coordinate) + + if (coordinate == final) { + return distance + } + + for ((y, x) in validAdjacentIndicesExtended(input, coordinate.y, coordinate.x)) { + val neighbour = Coordinate(y, x) + val alternative = distance + getDistance(input, y, x) + + if (alternative < (distances[neighbour] ?: Int.MAX_VALUE)) { + distances[neighbour] = alternative + queue.add(Pair(alternative, neighbour)) + } + } + } + return Int.MAX_VALUE +} + +fun main() { + val sample = readInput(15, "sample").map { row -> row.map { it.digitToInt() } } + val input = readInput(15, "input").map { row -> row.map { it.digitToInt() } } + + check(part1(sample) == 40) + println(part1(input)) + + check(part2(sample) == 315) + println(part2(input)) +} diff --git a/src/year2021/day15/sample.txt b/src/year2021/day15/sample.txt new file mode 100644 index 0000000..7d9d562 --- /dev/null +++ b/src/year2021/day15/sample.txt @@ -0,0 +1,10 @@ +1163751742 +1381373672 +2136511328 +3694931569 +7463417111 +1319128137 +1359912421 +3125421639 +1293138521 +2311944581 \ No newline at end of file