-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day17.kt
80 lines (63 loc) · 2.25 KB
/
Day17.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
70
71
72
73
74
75
76
77
78
79
80
package aoc2021.day17
import util.Coord
fun parseInput(inputString: String): Range {
val split = inputString.split(", ")
val splitX = split[0].replace("x=", "").split("..")
val splitY = split[1].replace("y=", "").split("..")
return Range(splitX[0].toInt(), splitX[1].toInt(), splitY[0].toInt(), splitY[1].toInt())
}
fun fireProbe(initHorizontalVelocity: Int, initVerticalVelocity: Int, range: Range): HitOrMiss {
val position = Coord(0, 0)
var maxYReached = position.y
var horizontalVelocity = initHorizontalVelocity
var verticalVelocity = initVerticalVelocity
while (!isPositionInRange(position, range)) {
if (verticalVelocity < -10000)
return HitOrMiss(false, maxYReached)
position.x += horizontalVelocity
position.y += verticalVelocity
if (maxYReached < position.y) {
maxYReached = position.y
}
if (horizontalVelocity > 0) {
horizontalVelocity--
} else if (horizontalVelocity < 0) {
horizontalVelocity++
}
verticalVelocity--
}
return HitOrMiss(true, maxYReached)
}
fun findAllInitialVelocities(range: Range): Int {
val initialVelocities = mutableSetOf<Velocity>()
for (x in 1..152) {
for (y in -160..160) {
if (fireProbe(x, y, range).hitTarget) {
initialVelocities.add(Velocity(x, y))
}
}
}
return initialVelocities.size
}
fun isPositionInRange(probePosition: Coord, range: Range): Boolean {
return isInHorizontalRange(probePosition, range) && isInVerticalRange(probePosition, range)
}
private fun isInHorizontalRange(probePosition: Coord, range: Range) =
probePosition.x >= range.minX && probePosition.x <= range.maxX
private fun isInVerticalRange(probePosition: Coord, range: Range) =
probePosition.y >= range.minY && probePosition.y <= range.maxY
class Range(val minX: Int, val maxX: Int, val minY: Int, val maxY: Int)
class HitOrMiss(val hitTarget: Boolean, val highestY: Int)
class Velocity(private val horizontalVelocity: Int, private val verticalVelocity: Int) {
override fun toString(): String {
return "($horizontalVelocity, $verticalVelocity)"
}
}
fun printGrid(range: Range) {
for (y in 0 downTo range.minY) {
for (x in 0..range.maxX) {
if (isPositionInRange(Coord(x, y), range)) print("T") else print(".")
}
println()
}
}