Untitled
unknown
rust
4 months ago
3.2 kB
22
Indexable
const ORDERING: [Ordering; 2] = [Ordering::Less, Ordering::Greater]; pub fn solution(test: bool) -> ((usize, Duration), (usize, Duration)) { let lines; if test { lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_14_test.txt"); } else { lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_14.txt"); } let room = Room::from_str(&lines); (solve01(&room), solve02(&room)) } fn solve01(room: &Room) -> (usize, Duration) { let mut room = room.clone(); let now = Instant::now(); for _ in 0..100 { room.step(); } (room.calc_safety() as usize, now.elapsed()) } fn solve02(room: &Room) -> (usize, Duration) { let mut room = room.clone(); let now = Instant::now(); let step = (0..room.bounds.0 * room.bounds.1) .map(|_| { let safety = room.calc_safety(); room.step(); safety }) .enumerate() .min_by_key(|(step, factor)| *factor) .unwrap(); (step.0 as usize, now.elapsed()) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct Robot { position: (isize, isize), velocity: (isize, isize), } impl Robot { fn from_str(s: &str) -> Self { let mut s = s.split(' '); let position = parse_vector(&mut s); let velocity = parse_vector(&mut s); Self { position, velocity } } fn step(&mut self, bounds: (isize, isize)) { self.position.0 += self.velocity.0; self.position.1 += self.velocity.1; self.position.0 = self.position.0.rem_euclid(bounds.0 + 1); self.position.1 = self.position.1.rem_euclid(bounds.1 + 1); } } #[derive(Debug, Clone)] struct Room { robots: Vec<Robot>, bounds: (isize, isize), } impl Room { fn from_str(s: &str) -> Self { let robots = s.lines().map(Robot::from_str).collect_vec(); let bounds = robots.iter().fold((0, 0), |acc, robot| { (acc.0.max(robot.position.0), acc.1.max(robot.position.1)) }); Self { robots, bounds } } fn step(&mut self) { for robot in &mut self.robots { robot.step(self.bounds); } } fn calc_safety(&self) -> usize { let mut counts = [0; 4]; for (i, (order_x, order_y)) in ORDERING .iter() .cartesian_product(ORDERING.iter()) .enumerate() { counts[i] = self .robots .iter() .filter(|robot| { robot.position.0.cmp(&(self.bounds.0 / 2)) == *order_x && robot.position.1.cmp(&(self.bounds.1 / 2)) == *order_y }) .count(); } counts.iter().product() } fn check_if_tree(&self) -> bool { self.robots .iter() .permutations(2) .all(|r| r[0].velocity != r[1].velocity) } } fn parse_vector(s: &mut std::str::Split<'_, char>) -> (isize, isize) { let vector = s .next() .unwrap() .split('=') .nth(1) .unwrap() .split(',') .map(|x| x.parse().unwrap()) .collect_tuple() .unwrap(); vector }
Editor is loading...
Leave a Comment