main.rs (1770B)
1 fn main() {
2 let x_range = (155, 215);
3 let y_range = (-132, -72);
4 // 8646
5 println!("Part 1: {}", part_1(x_range, y_range));
6 // 5945
7 println!("Part 2: {}", part_2(x_range, y_range));
8 }
9
10 fn fire(v: (i32, i32), x_range: (i32, i32), y_range: (i32, i32)) -> Option<()> {
11 let mut x = 0;
12 let mut y = 0;
13 let (mut x_v, mut y_v) = v;
14 while x <= x_range.1 && y >= y_range.0 {
15 x += x_v;
16 y += y_v;
17 y_v -= 1;
18 x_v -= x_v.signum();
19 if x >= x_range.0 && x <= x_range.1 && y >= y_range.0 && y <= y_range.1 {
20 return Some(());
21 }
22 }
23 None
24 }
25
26 fn part_1(x_range: (i32, i32), y_range: (i32, i32)) -> i32 {
27 // x_v * (x_v + 1) / 2 is final x pos
28 let x_v_min = ((2.0 * x_range.0 as f64 + 1.0).sqrt() - 1.0).floor() as i32;
29 let x_v_max = x_range.1;
30 // no point firing downwards
31 let y_v_min = 0;
32 // when crossing y=0 again, the speed is same as initial speed, just pointing downwards.
33 let y_v_max = y_range.0.abs();
34 let mut y_max = 0;
35 for x_v in x_v_min..=x_v_max {
36 for y_v in y_v_min..=y_v_max {
37 if let Some(_) = fire((x_v, y_v), x_range, y_range) {
38 y_max = y_max.max(y_v * (y_v + 1) / 2);
39 }
40 }
41 }
42 y_max
43 }
44
45 fn part_2(x_range: (i32, i32), y_range: (i32, i32)) -> i32 {
46 let x_v_min = ((2.0 * x_range.0 as f64 + 1.0).sqrt() - 1.0).floor() as i32;
47 let x_v_max = x_range.1;
48 let y_v_min = y_range.0;
49 let y_v_max = y_range.0.abs();
50 let mut arrive_count = 0;
51 for x_v in x_v_min..=x_v_max {
52 for y_v in y_v_min..=y_v_max {
53 if let Some(_) = fire((x_v, y_v), x_range, y_range) {
54 arrive_count += 1;
55 }
56 }
57 }
58 arrive_count
59 }