use regex::Regex; use std::collections::HashMap; static DAY: u8 = 14; fn main() { let input = advent::read_lines(DAY); println!("{DAY}a: {}", safety_factor(&input, Position { x: 101, y: 103 })); println!("{DAY}b: {}", 0); } struct Position { x: isize, y: isize, } struct Robot { pos: Position, velocity: Position, } impl Robot { fn new(input: &str) -> Robot { let re = Regex::new(r"p=([0-9]+),([0-9]+) v=([-0-9]+),([-0-9]+)").unwrap(); let caps = re.captures(input).unwrap(); let x = caps.get(1).unwrap().as_str().parse::().unwrap(); let y = caps.get(2).unwrap().as_str().parse::().unwrap(); let dx = caps.get(3).unwrap().as_str().parse::().unwrap(); let dy = caps.get(4).unwrap().as_str().parse::().unwrap(); Robot { pos: Position { x, y }, velocity: Position { x: dx, y: dy }, } } fn travel(&mut self, area: &Position) { self.pos.x = (self.pos.x + self.velocity.x + area.x) % area.x; self.pos.y = (self.pos.y + self.velocity.y + area.y) % area.y; } fn quadrant(&self, area: &Position) -> u8 { if self.pos.x < area.x / 2 && self.pos.y < area.y / 2 { 1 } else if self.pos.x < area.x / 2 && self.pos.y > area.y / 2 { 2 } else if self.pos.x > area.x / 2 && self.pos.y < area.y / 2 { 3 } else if self.pos.x > area.x / 2 && self.pos.y > area.y / 2 { 4 } else { 0 } } } fn safety_factor(input: &[String], area: Position) -> u32 { let mut robots = input.iter() .map(|line| Robot::new(line)) .collect::>(); for _ in 0 .. 100 { for robot in robots.iter_mut() { robot.travel(&area); } } let mut quadrants = HashMap::new(); for robot in &robots { let quadrant = robot.quadrant(&area); if quadrant != 0 { let entry = quadrants.entry(quadrant).or_insert(0); *entry += 1; } } quadrants.values().product() } #[cfg(test)] mod tests { use super::*; #[test] fn test() { let input = [ "p=0,4 v=3,-3", "p=6,3 v=-1,-3", "p=10,3 v=-1,2", "p=2,0 v=2,-1", "p=0,0 v=1,3", "p=3,0 v=-2,-2", "p=7,6 v=-1,-3", "p=3,0 v=-1,-2", "p=9,3 v=2,3", "p=7,3 v=-1,2", "p=2,4 v=2,-3", "p=9,5 v=-3,-3", ].iter().map(|&x| String::from(x)).collect::>(); assert_eq!(safety_factor(&input, Position { x: 11, y: 7}), 12); } }