generated from Jadarma/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathY2023D18.kt
61 lines (51 loc) · 2.42 KB
/
Y2023D18.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package aockt.y2023
import aockt.util.parse
import aockt.util.spacial.Direction
import aockt.util.spacial.Direction.*
import aockt.util.spacial.Point
import aockt.util.spacial.move
import aockt.util.spacial.polygonArea
import io.github.jadarma.aockt.core.Solution
object Y2023D18 : Solution {
/**
* A single step of a dig plan.
* @property direction The direction to dig in from the current point.
* @property length How long should the next segment be.
*/
private data class DigPlanStep(val direction: Direction, val length: Int)
/** Follow the [DigPlanStep]s from a [start] point, and return the coordinates of all corners of the polygon. */
private fun List<DigPlanStep>.digTrench(start: Point): List<Point> = buildList {
var point = start
for ((direction, length) in this@digTrench) {
point = point.move(direction, length.toLong())
add(point)
}
check(point == start) { "Trench invalid, did not loop back to start." }
}
/**
* Parse the input and return the dig plan.
* @param input The puzzle input.
* @param inColorEncoding Whether to take the steps from the colors or from the plain text.
*/
private fun parseInput(input: String, inColorEncoding: Boolean): List<DigPlanStep> = parse {
val stepRegex = Regex("""^([LRUD]) (\d+) \(#([0-9a-f]{6})\)$""")
val directions = listOf(Right, Down, Left, Up)
fun String.parseDirection(): Direction = directions["RDLU".indexOf(first())]
fun String.parseColorPlan(): DigPlanStep = DigPlanStep(
direction = directions[last().digitToInt()],
length = substring(0, 5).toInt(16),
)
input
.lineSequence()
.map { stepRegex.matchEntire(it)!!.destructured }
.map { (direction, length, color) ->
if (inColorEncoding) color.parseColorPlan()
else DigPlanStep(direction.parseDirection(), length.toInt())
}
.toList()
}
/** Simulate digging a trench following the steps, and return the total volume of the hollowed out structure. */
private fun List<DigPlanStep>.solve(): Long = digTrench(Point.Origin).polygonArea(includingPerimeter = true)
override fun partOne(input: String) = parseInput(input, inColorEncoding = false).solve()
override fun partTwo(input: String) = parseInput(input, inColorEncoding = true).solve()
}