-
Notifications
You must be signed in to change notification settings - Fork 2
/
Day09.kt
69 lines (55 loc) · 1.96 KB
/
Day09.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
62
63
64
65
66
67
68
69
/*
* Copyright (c) 2022 by Todd Ginsberg
*/
/**
* Advent of Code 2022, Day 9 - Rope Bridge
* Problem Description: http://adventofcode.com/2022/day/9
* Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2022/day9/
*/
package com.ginsberg.advent2022
import kotlin.math.absoluteValue
import kotlin.math.sign
class Day09(input: List<String>) {
private val headPath: String = parseInput(input)
fun solvePart1(): Int =
followPath(2)
fun solvePart2(): Int =
followPath(10)
private fun followPath(knots: Int): Int {
val rope = Array(knots) { Point() }
val tailVisits = mutableSetOf(Point())
headPath.forEach { direction ->
rope[0] = rope[0].move(direction)
rope.indices.windowed(2, 1) { (head, tail) ->
if (!rope[head].touches(rope[tail])) {
rope[tail] = rope[tail].moveTowards(rope[head])
}
}
tailVisits += rope.last()
}
return tailVisits.size
}
private data class Point(val x: Int = 0, val y: Int = 0) {
fun move(direction: Char): Point =
when (direction) {
'U' -> copy(y = y - 1)
'D' -> copy(y = y + 1)
'L' -> copy(x = x - 1)
'R' -> copy(x = x + 1)
else -> throw IllegalArgumentException("Unknown Direction: $direction")
}
fun moveTowards(other: Point): Point =
Point(
(other.x - x).sign + x,
(other.y - y).sign + y
)
fun touches(other: Point): Boolean =
(x - other.x).absoluteValue <= 1 && (y - other.y).absoluteValue <= 1
}
private fun parseInput(input: List<String>): String =
input.joinToString("") { row ->
val direction = row.substringBefore(" ")
val numberOfMoves = row.substringAfter(' ').toInt()
direction.repeat(numberOfMoves)
}
}