diff --git a/2021/src/day17.rs b/2021/src/day17.rs new file mode 100644 index 0000000..d5e01a3 --- /dev/null +++ b/2021/src/day17.rs @@ -0,0 +1,81 @@ +use std::ops::Range; + +use color_eyre::eyre; + + +#[derive(Default, Debug)] +struct Pair { + x: i64, + y: i64 +} + +#[derive(Debug)] +struct ProbeState { + pos: Pair, + vel: Pair, +} + +struct Zone { + x: Range, + y: Range, +} + + +impl ProbeState { + fn new(vx: i64, vy: i64) -> Self { + let vel = Pair {x: vx, y: vy}; + ProbeState {pos: Pair::default(), vel} + } + + fn step(&mut self) { + self.pos.x += self.vel.x; + self.pos.y += self.vel.y; + self.vel.y -= 1; + if self.vel.x > 0 { + self.vel.x -= 1; + } + } + + fn is_in(&self, zone: Zone) -> bool { + zone.x.contains(&self.pos.x) && zone.y.contains(&self.pos.y) + } + + fn is_past(&self, zone: Zone) -> bool { + self.pos.x >= zone.x.end || self.pos.y <= zone.y.start + } +} + + +const VX_MIN: i64 = 23; +const VX_MAX: i64 = 293; +const VY_MIN: i64 = -69; +const VY_MAX: i64 = 68; +const TARGET: Zone = Zone {x: 269..293, y: -68..-43}; + + +//sample data +// const VX_MIN: i64 = 6; +// const VX_MAX: i64 = 31; +// const VY_MIN: i64 = -11; +// const VY_MAX: i64 = 10; +// const TARGET: Zone = Zone {x: 20..31, y: -10..-4}; + + +pub fn run(_data: &str) -> eyre::Result<(usize, usize)> { + let mut total = 0; + // just brute force it, there are only ~35k possibilities + for vx in VX_MIN..VX_MAX { + for vy in VY_MIN..VY_MAX { + let mut state = ProbeState::new(vx, vy); + while !state.is_past(TARGET) { + state.step(); + if state.is_in(TARGET) { + total += 1; + break; + } + } + } + } + + Ok((2278, total)) +} diff --git a/2021/src/main.rs b/2021/src/main.rs index 424d2c9..5ab2a30 100644 --- a/2021/src/main.rs +++ b/2021/src/main.rs @@ -4,14 +4,14 @@ use color_eyre::eyre; mod lib; use lib::load; -mod day16; +mod day17; fn main() -> eyre::Result<()> { - let data = load("data/16.txt")?; + let data = load("data/17.txt")?; let start = Instant::now(); - let (one, two) = day16::run(&data)?; + let (one, two) = day17::run(&data)?; let (dur, unit) = format_ns(start.elapsed().as_nanos()); let precision = 2.0 - dur.log10().floor();