use nom::{ bytes::complete::tag, character::complete::i32 as nom_i32, combinator::map, sequence::tuple, IResult, }; use std::fs; fn main() -> Result<(), Box> { let input = fs::read_to_string("inputs/day_17.txt")?; let target = parse_target(&input).unwrap().1; let max_y_throw = 0 - target.min_y - 1; let max_height = max_y_throw * (max_y_throw + 1) / 2; dbg!(max_height); let min_y_throw = target.min_y; let max_x_throw = target.max_x; let min_x_throw = (2.0 * target.min_x as f32).sqrt() as i32; let mut count = 0; for x in min_x_throw..=max_x_throw { for y in min_y_throw..=max_y_throw { if simulate_throw(x, y, &target) { count += 1; } } } dbg!(count); Ok(()) } fn simulate_throw(mut x_vel: i32, mut y_vel: i32, target: &TargetArea) -> bool { let mut x_pos = 0; let mut y_pos = 0; loop { x_pos += x_vel; y_pos += y_vel; if x_vel > 0 { x_vel -= 1; } y_vel -= 1; if x_pos >= target.min_x && x_pos <= target.max_x && y_pos >= target.min_y && y_pos <= target.max_y { return true; } if x_pos > target.max_x || y_pos < target.min_y { return false; } } } #[derive(Debug)] struct TargetArea { min_x: i32, max_x: i32, min_y: i32, max_y: i32, } fn parse_target(input: &str) -> IResult<&str, TargetArea> { map( tuple(( tag("target area: x="), nom_i32, tag(".."), nom_i32, tag(", y="), nom_i32, tag(".."), nom_i32, )), |(_, min_x, _, max_x, _, min_y, _, max_y)| TargetArea { min_x, max_x, min_y, max_y, }, )(input) }