-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day09RopeBridge.kt
54 lines (44 loc) · 2.06 KB
/
Day09RopeBridge.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
package adventofcode.year2022
import adventofcode.Puzzle
import adventofcode.PuzzleInput
import adventofcode.common.Tuple.minus
import adventofcode.common.Tuple.plus
import adventofcode.year2022.Day09RopeBridge.Companion.Direction.D
import adventofcode.year2022.Day09RopeBridge.Companion.Direction.L
import adventofcode.year2022.Day09RopeBridge.Companion.Direction.R
import adventofcode.year2022.Day09RopeBridge.Companion.Direction.U
import kotlin.math.abs
import kotlin.math.sign
class Day09RopeBridge(customInput: PuzzleInput? = null) : Puzzle(customInput) {
private val motionMoves by lazy {
input.lines().map { line -> line.split(" ") }.map { (direction, steps) -> MotionMove(Direction.valueOf(direction), steps.toInt()) }
}
override fun partOne() = motionMoves.simulate(2).second.count()
override fun partTwo() = motionMoves.simulate(10).second.count()
companion object {
private enum class Direction { D, L, R, U }
private data class MotionMove(val direction: Direction, val steps: Int)
private fun List<MotionMove>.simulate(knotCount: Int) =
fold(List(knotCount) { (0 to 0) } to setOf(0 to 0)) { (knots, tailVisited), (direction, steps) ->
(1..steps).fold(knots to tailVisited) { (knots, tailVisited), _ ->
val newKnots = knots
.drop(1)
.fold(listOf(knots.first().move(direction))) { knotList, knot -> knotList + knot.track(knotList.last()) }
newKnots to tailVisited + newKnots.last()
}
}
private fun Pair<Int, Int>.move(direction: Direction) = when (direction) {
D -> this + (0 to -1)
L -> this + (-1 to 0)
R -> this + (1 to 0)
U -> this + (0 to 1)
}
private fun Pair<Int, Int>.track(other: Pair<Int, Int>): Pair<Int, Int> {
val (dx, dy) = other - this
return when {
abs(dx) < 2 && abs(dy) < 2 -> this
else -> this + (dx.sign to dy.sign)
}
}
}
}