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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
fn main() {
let (x1, x2) = (269, 292);
let (y1, y2) = (-68, -44);
println!("17a: {}", highest_y(x1, x2, y1, y2));
println!("17b: {}", count_velocities(x1, x2, y1, y2));
}
fn hit_target_y(velocity: i64, y1: i64, y2: i64, steps: i64) -> bool {
let mut pos = 0;
let mut velocity = velocity;
/* steps already done until 0 is reached again */
let initial_steps = velocity * 2 + 1;
for _ in initial_steps .. steps {
velocity += 1;
pos -= velocity;
}
pos >= y1 && pos <= y2
}
fn hit_target_x(velocity: i64, x1: i64, x2: i64, steps: i64) -> bool {
let mut pos = 0;
let mut velocity = velocity;
for _ in 0 .. steps {
pos += velocity;
velocity -= 1;
velocity = std::cmp::max(0, velocity);
}
pos >= x1 && pos <= x2
}
fn peak_y(velocity: i64) -> i64 {
velocity * (velocity + 1) / 2
}
fn highest_y(x1: i64, x2: i64, y1: i64, y2: i64) -> i64 {
let mut max = 0;
for vel_x in 1 .. 1000 {
for vel_y in 0 .. 1000 {
for steps in 1 .. 150 {
if hit_target_x(vel_x, x1, x2, steps) && hit_target_y(vel_y, y1, y2, steps) {
max = std::cmp::max(max, peak_y(vel_y));
break;
}
}
}
}
max
}
fn count_velocities(x1: i64, x2: i64, y1: i64, y2: i64) -> i64 {
let mut count = 0;
for vel_x in 1 .. 1000 {
for vel_y in -1000 .. 1000 {
for steps in 1 .. 150 {
if hit_target_x(vel_x, x1, x2, steps) && hit_target_y(vel_y, y1, y2, steps) {
count += 1;
break;
}
}
}
}
count
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let (x1, x2) = (20, 30);
let (y1, y2) = (-10, -5);
assert!(!hit_target_x(7, x1, x2, 3));
assert!(hit_target_x(7, x1, x2, 4));
assert!(hit_target_x(7, x1, x2, 5));
assert!(hit_target_x(7, x1, x2, 6));
assert!(hit_target_x(7, x1, x2, 7));
assert!(!hit_target_y(2, y1, y2, 6));
assert!(hit_target_y(2, y1, y2, 7));
assert!(!hit_target_y(2, y1, y2, 8));
assert!(!hit_target_x(6, x1, x2, 4));
assert!(hit_target_x(6, x1, x2, 5));
assert!(hit_target_x(6, x1, x2, 6));
assert!(hit_target_x(6, x1, x2, 7));
assert!(hit_target_x(6, x1, x2, 8));
assert!(hit_target_x(6, x1, x2, 9));
assert!(hit_target_x(6, x1, x2, 10));
assert!(!hit_target_y(3, y1, y2, 8));
assert!(hit_target_y(3, y1, y2, 9));
assert!(!hit_target_y(3, y1, y2, 10));
assert_eq!(highest_y(x1, x2, y1, y2), 45);
assert_eq!(count_velocities(x1, x2, y1, y2), 112);
}
}
|