2021-12-17 13:58:03 +01:00
|
|
|
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 {
|
2021-12-17 14:25:34 +01:00
|
|
|
if vx > 0 {
|
|
|
|
vx -= 1;
|
|
|
|
} else {
|
|
|
|
vx += 1;
|
|
|
|
}
|
2021-12-17 13:58:03 +01:00
|
|
|
}
|
|
|
|
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::<i64>().unwrap(),
|
|
|
|
cap[2].parse::<i64>().unwrap(),
|
|
|
|
cap[3].parse::<i64>().unwrap(),
|
|
|
|
cap[4].parse::<i64>().unwrap(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
|
|
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;
|
|
|
|
|
2021-12-17 14:25:34 +01:00
|
|
|
for vx in 0..256 {
|
2021-12-17 13:58:03 +01:00
|
|
|
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(())
|
|
|
|
}
|