1+ package dev.manka.advent_of_code.days.y2021
2+
3+ import dev.manka.advent_of_code.days.Day
4+ import kotlin.math.absoluteValue
5+ import kotlin.math.sign
6+
7+ class Day17 : Day (17 , " Trick Shot" ) {
8+
9+ override fun partOne (): String {
10+ val targetArea = TargetArea (inputList.first())
11+ return (0 .. targetArea.x.last).maxOf { x ->
12+ (targetArea.y.first.. targetArea.y.first.absoluteValue)
13+ .map { y -> trajectory((x to y)).takeWhile { ! targetArea.hasOvershot(it) } }
14+ .filter { it.any { p -> targetArea.has(p) } }
15+ .maxOfOrNull { it.maxOf { p -> p.second } } ? : 0
16+ }.toString()
17+ }
18+
19+ override fun partTwo (): String {
20+ val targetArea = TargetArea (inputList.first())
21+ return (0 .. targetArea.x.last).sumOf { x ->
22+ (targetArea.y.first.. targetArea.y.first.absoluteValue)
23+ .map { y -> trajectory(x to y).first { targetArea.hasOvershot(it) || targetArea.has(it) } }
24+ .count { targetArea.has(it) }
25+ }.toString()
26+ }
27+
28+ private fun trajectory (velocity : Pair <Int , Int >): Sequence <Pair <Int , Int >> = sequence {
29+ var x = 0
30+ var y = 0
31+ var Vx = velocity.first
32+ var Vy = velocity.second
33+ while (true ) {
34+ x + = Vx
35+ y + = Vy
36+ Vx + = if (Vx == 0 ) 0 else Vx .sign * - 1
37+ Vy - = 1
38+ yield (x to y)
39+ }
40+ }
41+
42+ private class TargetArea (input : String ) {
43+ val x: IntRange = input.substringAfter(" =" ).substringBefore(" ." ).toInt()..
44+ input.substringAfter(" .." ).substringBefore(" ," ).toInt()
45+ val y: IntRange = input.substringAfterLast(" =" ).substringBefore(" ." ).toInt()..
46+ input.substringAfterLast(" ." ).toInt()
47+
48+ fun has (point : Pair <Int , Int >): Boolean = point.first in x && point.second in y
49+
50+ fun hasOvershot (point : Pair <Int , Int >): Boolean = point.first > x.last || point.second < y.first
51+ }
52+
53+
54+ }
0 commit comments