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 }