use nom::{ bytes::complete::tag, character::complete::{i64, multispace1}, multi::separated_list1, sequence::{preceded, separated_pair}, IResult, }; fn parse(input: &str) -> IResult<&str, Vec<((i64, i64), (i64, i64))>> { let (input, result) = separated_list1( multispace1, separated_pair( separated_pair(preceded(tag("p="), i64), tag(","), i64), tag(" v="), separated_pair(i64, tag(","), i64), ), )(input)?; Ok((input, result)) } fn calc_pos( start_pos: (i64, i64), velocity: (i64, i64), width: i64, height: i64, time: i64, ) -> (i64, i64) { let x = (start_pos.0 + velocity.0 * time).rem_euclid(width); let y = (start_pos.1 + velocity.1 * time).rem_euclid(height); (x, y) } fn solve_1(input: &str, width: i64, height: i64) -> i64 { let (_, result) = parse(input).unwrap(); let (mut q1, mut q2, mut q3, mut q4) = (0, 0, 0, 0); for (x_end, y_end) in result .into_iter() .map(|(pos, vel)| calc_pos(pos, vel, width, height, 100)) { if x_end < width / 2 && y_end < height / 2 { q1 += 1; } else if x_end > width / 2 && y_end < height / 2 { q2 += 1; } else if x_end < width / 2 && y_end > height / 2 { q3 += 1; } else if x_end > width / 2 && y_end > height / 2 { q4 += 1; } } q1 * q2 * q3 * q4 } fn solve_2(input: &str, width: i64, height: i64) -> i64 { let (_, mut robots) = parse(input).unwrap(); let mut min_e = i64::MAX; let mut time = 0; for t in 0..=100000 { let (mut q1, mut q2, mut q3, mut q4) = (0, 0, 0, 0); for (pos, vel) in robots.iter_mut() { *pos = calc_pos(*pos, *vel, width, height, 1); if pos.0 < width / 2 && pos.1 < height / 2 { q1 += 1; } else if pos.0 > width / 2 && pos.1 < height / 2 { q2 += 1; } else if pos.0 < width / 2 && pos.1 > height / 2 { q3 += 1; } else if pos.0 > width / 2 && pos.1 > height / 2 { q4 += 1; } } let e = q1 * q2 * q3 * q4; if min_e > e { time = t; min_e = e; } } time + 1 } fn main() { println!("Hello, this is Patrick!"); let input = include_str!("../input.txt"); let result_1 = solve_1(input, 101, 103); println!("The safety factor will be {}", result_1); let result_2 = solve_2(input, 101, 103); println!("The time that the easter egg occurs is {}s", result_2); } #[cfg(test)] mod tests { use super::*; #[test] fn test_1() { let test_input = include_str!("../test.txt"); assert_eq!(solve_1(test_input, 11, 7), 12); } //#[test] //fn test_2() { // //let test_input = include_str!("../test.txt"); // //assert_eq!(solve_2(test_input), _); //} }