use std::error::Error; use std::fs::File; use std::io::{self, BufRead}; #[macro_use] extern crate lazy_static; extern crate regex; use regex::Regex; fn is_hit( mut vx: i64, mut vy: i64, target_min_x: i64, target_max_x: i64, target_min_y: i64, target_max_y: i64, ) -> (bool, i64) { let mut x: i64 = 0; let mut y: i64 = 0; let mut max_y = y; while x < target_max_x && y > target_min_y { x += vx; y += vy; if y > max_y { max_y = y; } if vx != 0 { if vx > 0 { vx -= 1; } else { vx += 1; } } vy -= 1; if x >= target_min_x && x <= target_max_x && y >= target_min_y && y <= target_max_y { return (true, max_y); } } (false, 0) } fn parse_line(line: &str) -> (i64, i64, i64, i64) { lazy_static! { static ref LINE_RE: Regex = Regex::new(r"^target area: x=([0-9]+)\.\.([0-9]+), y=(-[0-9]+)\.\.(-[0-9]+)$").unwrap(); } let cap = LINE_RE.captures_iter(&line).nth(0).unwrap(); ( cap[1].parse::().unwrap(), cap[2].parse::().unwrap(), cap[3].parse::().unwrap(), cap[4].parse::().unwrap(), ) } fn main() -> Result<(), Box> { let file = File::open("inputs/day17.txt")?; let line: String = io::BufReader::new(file).lines().next().unwrap()?; let target = parse_line(&line); let mut max_y = 0; let mut max_velocities = (0, 0); for vx in 0..256 { for vy in 0..246 { let (hit, local_max_y) = is_hit(vx, vy, target.0, target.1, target.2, target.3); if hit { println!("Hit {} {}: {}", vx, vy, max_y); if local_max_y > max_y { max_y = local_max_y; max_velocities = (vx, vy); } } } } println!("Velocities: {},{}", max_velocities.0, max_velocities.1); println!("Answer1: {}", max_y); let mut hits = 0; for vx in 0..256 { for vy in -256..246 { let (hit, local_max_y) = is_hit(vx, vy, target.0, target.1, target.2, target.3); if hit { println!("Hit {} {}: {}", vx, vy, local_max_y); hits += 1; } } } println!("Answer2: {}", hits); Ok(()) }