Day 10: Hoof It
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
You are viewing a single thread.
View all comments 1 point
Kotlin
- Clean ❌
- Fast ❌
- Worked first try ✅
Code:
fun main() {
/**
* The idea is simple: Just simulate the pathing and sum all the end points
*/
fun part1(input: List<String>): Int {
val topologicalMap = Day10Map(input)
val startingPoints = topologicalMap.asIterable().indicesWhere { it == 0 }
val directions = Orientation.entries.map { it.asVector() }
return startingPoints.sumOf { startingPoint ->
var wayPoints = setOf(VecNReal(startingPoint))
val endPoints = mutableSetOf<VecNReal>()
while (wayPoints.isNotEmpty()) {
wayPoints = wayPoints.flatMap { wayPoint ->
directions.map { direction ->
val checkoutLocation = wayPoint + direction
checkoutLocation to runCatching { topologicalMap[checkoutLocation] }.getOrElse { -1 }
}.filter { nextLocation ->
val endPointHeight = topologicalMap[wayPoint]
if (nextLocation.second - 1 == endPointHeight && nextLocation.second == 9) false.also { endPoints.add(nextLocation.first) }
else if (nextLocation.second - 1 == endPointHeight) true
else false
}.map { it.first }
}.toSet()
}
endPoints.count()
}
}
/**
* A bit more complicated, but not by much.
* Main difference is, that node accumulates all the possible paths, thus adding all the possibilities of
* its parent node.
*/
fun part2(input: List<String>): Int {
val topologicalMap = Day10Map(input)
val startingPoints = topologicalMap.asIterable().indicesWhere { it == 0 }
val directions = Orientation.entries.map { it.asVector() }
return startingPoints.sumOf { startingPoint ->
var pathNodes = setOf<Node>(Node(VecNReal(startingPoint), topologicalMap[VecNReal(startingPoint)], 1))
val endNodes = mutableSetOf<Node>()
while (pathNodes.isNotEmpty()) {
pathNodes = pathNodes.flatMap { pathNode ->
directions.map { direction ->
val nextNodeLocation = pathNode.position + direction
val nextNodeHeight = runCatching { topologicalMap[nextNodeLocation] }.getOrElse { -1 }
Node(nextNodeLocation, nextNodeHeight, pathNode.weight)
}.filter { nextNode ->
nextNode.height == pathNode.height + 1
}
}.groupBy { it.position }.map { (position, nodesUnadjusted) ->
val adjustedWeight = nodesUnadjusted.sumOf { node -> node.weight }
Node(position, nodesUnadjusted.first().height, adjustedWeight)
}.filter { node ->
if (node.height == 9) false.also { endNodes.add(node) } else true
}.toSet()
}
endNodes.sumOf { endNode -> endNode.weight }
}
}
val testInput = readInput("Day10_test")
check(part1(testInput) == 36)
check(part2(testInput) == 81)
val input = readInput("Day10")
part1(input).println()
part2(input).println()
}
class Day10Map(input: List<String>): Grid2D<Int>(input.map { row -> row.map { "$it".toInt() } }) {
init { transpose() }
}
data class Node(val position: VecNReal, val height: Int, val weight: Int = 1)