diff --git a/2021/src/day17.rs b/2021/src/day17.rs index 778ada0..a7db66e 100644 --- a/2021/src/day17.rs +++ b/2021/src/day17.rs @@ -9,6 +9,31 @@ struct Target { y_max: isize, } +impl Target { + fn hit(&self, x: isize, y: isize) -> bool { + x >= self.x_min && x <= self.x_max && y >= self.y_min && y <= self.y_max + } +} + +fn shoot(x: isize, y: isize, tgt: &Target) -> bool { + let mut x_inc = x; + let mut y_inc = y; + let mut x_cur = 0; + let mut y_cur = 0; + while x_cur <= tgt.x_max && y_cur >= tgt.y_min { + x_cur += x_inc; + y_cur += y_inc; + if x_inc > 0 { + x_inc -= 1; + } + y_inc -= 1; + if tgt.hit(x_cur, y_cur) { + return true; + } + } + false +} + impl FromStr for Target { type Err = Infallible; @@ -35,19 +60,26 @@ impl FromStr for Target { } #[aoc(day17, part1)] -fn part1(input: &str) -> Result { +fn part1(input: &str) -> Result { let tgt: Target = input.parse()?; - dbg!(&tgt); - Ok((0..(tgt.y_min).abs() as usize).sum()) + let n = tgt.y_min.abs() - 1; + Ok(n * (n + 1) / 2) } -/* #[aoc(day17, part2)] fn part2(input: &str) -> Result { - todo!("part2"); - Ok(0) + let tgt: Target = input.parse()?; + let mut cnt = 0; + let y_range = tgt.y_min.abs().max(tgt.y_min.abs()); + for y in -y_range..=y_range { + for x in 1..=tgt.x_max { + if shoot(x, y, &tgt) { + cnt += 1; + } + } + } + Ok(cnt) } -*/ #[cfg(test)] mod tests { @@ -63,14 +95,13 @@ target area: x=20..30, y=-10..-5 Ok(()) } - /* #[test] - fn test_part2()->Result<()> { + fn test_part2() -> Result<()> { let input = r#" - "# +target area: x=20..30, y=-10..-5 +"# .trim(); - assert_eq!(part2(input)?, usize::MAX); - Ok(()) + assert_eq!(part2(input)?, 112); + Ok(()) } - */ }