From ba06e006b96c8e66b9d604e7e2198dcedc3c702a Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Fri, 17 Dec 2021 18:32:18 +0100 Subject: [PATCH] 2021: day17: part 2 --- aoc2021/src/day17.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/aoc2021/src/day17.rs b/aoc2021/src/day17.rs index b3734b6..9e6ab15 100644 --- a/aoc2021/src/day17.rs +++ b/aoc2021/src/day17.rs @@ -10,6 +10,7 @@ pub fn run() -> Result { let mut res = String::with_capacity(128); writeln!(res, "part 1: {}", part1(INPUT)?)?; + writeln!(res, "part 2: {}", part2(INPUT)?)?; Ok(res) } @@ -51,6 +52,42 @@ fn part1(input: &str) -> Result { .context("couldn't find any trajectory") } +fn part2(input: &str) -> Result { + let area: TargetArea = input + .parse() + .context("couldn't parse input to target area")?; + + let min_x_vel = if area.min_x() > 0 { + (0..).find(|x| ((x * (x + 1)) / 2) >= area.min_x()).unwrap() + } else if area.max_x() < 0 { + -(0..) + .find(|x| ((x * (x + 1)) / 2) >= area.max_x().abs()) + .unwrap() + } else { + 0 + }; + + let max_x_vel = if area.min_x() > 0 { + area.max_x() + } else if area.max_x() < 0 { + area.min_x() + } else { + 0 + }; + + // Rust ranges can only be increasing, so swap values around if negative + let (min_x_vel, max_x_vel) = (min_x_vel.min(max_x_vel), min_x_vel.max(max_x_vel)); + + // let's assume that the area is always lower than (0, 0) + let min_y_vel = area.min_y(); + let max_y_vel = area.min_y().abs(); + + Ok((min_x_vel..=max_x_vel) + .flat_map(|x_vel| (min_y_vel..=max_y_vel).map(move |y_vel| (x_vel, y_vel))) + .filter_map(|(x_vel, y_vel)| throw(x_vel, y_vel, &area)) + .count()) +} + fn throw(mut xvel: isize, mut yvel: isize, area: &TargetArea) -> Option { let (mut pos_x, mut pos_y) = (0, 0); let mut highest_y = 0; @@ -156,4 +193,14 @@ mod tests { fn part1_real() { assert_eq!(part1(INPUT).unwrap(), 4186); } + + #[test] + fn part2_provided() { + assert_eq!(part2(PROVIDED).unwrap(), 112); + } + + #[test] + fn part2_real() { + assert_eq!(part2(INPUT).unwrap(), 2709); + } }