use std::{ collections::{HashMap, HashSet}, thread, time::Duration, }; use advent_of_code_2024::{make_main, next, Pair, SResult}; use regex::Regex; make_main!(); fn solve(lines: Vec) -> SResult<(usize, usize)> { // NOTE: this needs to be adjusted for the size of the grid let dims = (101, 103); let pos_regex = Regex::new(r"p=(?\d+),(?\d+) v=(?-?\d+),(?-?\d+)").unwrap(); let mut robots = vec![]; for line in lines { let caps = pos_regex.captures(&line.trim()).unwrap(); let x = caps["x"].parse::().unwrap(); let y = caps["y"].parse::().unwrap(); let xvel = caps["xvel"].parse::().unwrap(); let yvel = caps["yvel"].parse::().unwrap(); robots.push(Robot { vel: (xvel, yvel), pos: (x, y), }) } // Simulation GO // 79, 388, 491, 697, 800, 903, 1006, 1109, 1212, 1315 let millis = Duration::from_millis(10); let mut n = 0; let mut tens = 11usize; let mut ones = 24usize; loop { if (n / 100 == tens && n % 100 == ones) || (n >= 800 && (n - 800) % 103 == 0) { print!("{}[2J", 27 as char); println!("{}", n); print_grid(&robots, dims); if (n / 100 == tens && n % 100 == ones) { tens += 1; ones += 1; } thread::sleep(millis); } n += 1; for robot in robots.iter_mut() { robot.advance(dims); } } //Ok((calc_safety(&robots, dims).iter().fold(1, |x, y| x * y), 0)) } #[derive(Debug)] struct Robot { vel: Pair, pos: Pair, } impl Robot { fn advance(&mut self, dims: Pair) { self.pos.0 = roll(self.pos.0, self.vel.0, dims.0); self.pos.1 = roll(self.pos.1, self.vel.1, dims.1); } } fn roll(pos: usize, vel: i64, dim: usize) -> usize { let ipos = pos as i64; if ipos + vel >= 0 { ((ipos + vel) as usize) % dim } else { ((ipos + vel) + dim as i64) as usize } } fn calc_safety(robots: &[Robot], dims: Pair) -> [usize; 4] { let mut scores = [0usize; 4]; for robot in robots { let xhalf = part(robot.pos.0, dims.0); let yhalf = part(robot.pos.1, dims.1); match (xhalf, yhalf) { (0, 0) => scores[0] += 1, (0, 1) => scores[1] += 1, (1, 0) => scores[2] += 1, (1, 1) => scores[3] += 1, _ => { // Do nothing; this is expected } } } scores } fn part(pos: usize, dim: usize) -> usize { if pos < dim / 2 { 0 } else if pos > dim / 2 { 1 } else { 2 } } fn print_grid(robots: &[Robot], dims: Pair) { println!(""); let mut pos = HashMap::new(); for rob in robots { *pos.entry(rob.pos).or_insert(0) += 1; } for j in 0..dims.1 { for i in 0..dims.0 { if let Some(count) = pos.get(&(i, j)) { print!("{}", count); } else { print!(" "); } } println!(""); } println!(""); } #[cfg(test)] mod tests { use advent_of_code_2024::input; use super::*; #[test] fn d14p1() { return; let strings: Vec = input!("d14p1.txt"); let got = solve(strings).unwrap(); assert_eq!(got, (12, 0)); } }