diff options
Diffstat (limited to '2021/day17')
-rw-r--r-- | 2021/day17/.gitignore | 1 | ||||
-rw-r--r-- | 2021/day17/Cargo.lock | 42 | ||||
-rw-r--r-- | 2021/day17/Cargo.toml | 9 | ||||
-rw-r--r-- | 2021/day17/src/main.rs | 90 |
4 files changed, 142 insertions, 0 deletions
diff --git a/2021/day17/.gitignore b/2021/day17/.gitignore new file mode 100644 index 0000000..9f97022 --- /dev/null +++ b/2021/day17/.gitignore @@ -0,0 +1 @@ +target/
\ No newline at end of file diff --git a/2021/day17/Cargo.lock b/2021/day17/Cargo.lock new file mode 100644 index 0000000..b5feb35 --- /dev/null +++ b/2021/day17/Cargo.lock @@ -0,0 +1,42 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "day17" +version = "0.1.0" +dependencies = [ + "regex", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" diff --git a/2021/day17/Cargo.toml b/2021/day17/Cargo.toml new file mode 100644 index 0000000..0f39b6d --- /dev/null +++ b/2021/day17/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day17" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +regex = "1" diff --git a/2021/day17/src/main.rs b/2021/day17/src/main.rs new file mode 100644 index 0000000..641962e --- /dev/null +++ b/2021/day17/src/main.rs @@ -0,0 +1,90 @@ +use regex::Regex; +use std::{fs::read_to_string, ops::Range}; + +#[derive(Debug, Clone, Copy)] +struct Coord(isize, isize); + +#[derive(Debug, Clone)] +struct TargetArea(pub Range<isize>, pub Range<isize>); +impl TargetArea { + fn contains(&self, c: Coord) -> bool { + self.0.contains(&c.0) && self.1.contains(&c.1) + } +} + +fn parse_target_area(line: &str) -> TargetArea { + let x_caps = Regex::new(r"x=([-\d]*)..([-\d]*)") + .unwrap() + .captures(line) + .unwrap(); + let y_caps = Regex::new(r"y=([-\d]*)..([-\d]*)") + .unwrap() + .captures(line) + .unwrap(); + + TargetArea( + x_caps[1].parse().unwrap()..x_caps[2].parse::<isize>().unwrap() + 1isize, + y_caps[1].parse().unwrap()..y_caps[2].parse::<isize>().unwrap() + 1isize, + ) +} + +fn does_intersect(mut vx: isize, mut vy: isize, area: &TargetArea) -> bool { + let mut x = 0; + let mut y = 0; + for _ in 0.. { + x += vx; + y += vy; + + vx = if vx > 0 { + vx - 1 + } else if vx < 0 { + vx + 1 + } else { + 0 + }; + vy -= 1; + if area.contains(Coord(x, y)) { + return true; + } else if x > area.0.end || y < area.1.start { + return false; + } + } + + unreachable!() +} + +fn max_y(mut vy: isize) -> isize { + let mut y = 0; + for _ in 0.. { + y += vy; + vy -= 1; + + if vy <= 0 { + return y; + } + } + + unreachable!() +} + +fn main() { + let area = parse_target_area(&read_to_string("./input").unwrap()); + + let mut max_y_found = 0; + let mut max_y_vel = Coord(0, 0); + let mut num_valid = 0; + for vx in 0..=area.0.end * 2 { + for vy in -area.1.start.abs() * 2..=area.1.start.abs() * 2 { + if does_intersect(vx, vy, &area) { + if max_y(vy) > max_y_found { + max_y_found = max_y(vy); + max_y_vel = Coord(vx, vy); + } + num_valid += 1; + } + } + } + + println!("part 1: {} with velocity {:?}", max_y_found, max_y_vel); + println!("part 2: {} possible velocities", num_valid); +} |