From 3872264523e9fb860cefae93f54efd23b85e91b1 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Tue, 13 Aug 2019 00:06:04 -0400 Subject: [PATCH] Completed day 13 part 2 --- src/day13.rs | 60 ++++++++++++++++++++++++++++++++++++++++++---------- src/main.rs | 2 ++ 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/day13.rs b/src/day13.rs index 582da90..e4ad8f1 100644 --- a/src/day13.rs +++ b/src/day13.rs @@ -48,6 +48,12 @@ struct Track { intersections: HashSet, } +#[derive(Debug, PartialEq)] +struct Collision { + position: Vector, + cart_indices: (usize, usize), +} + impl FromStr for Track { type Err = Box; @@ -87,7 +93,7 @@ impl FromStr for Track { }, (col_index, '/') => match bottom_start { Some(start) => match incomplete_circuits.remove(&(start, col_index)) { - Some(top_row) => { + Some(_) => { turns.insert( Vector { x: col_index, @@ -210,13 +216,18 @@ impl Cart { } impl Track { - fn run_tick(&mut self) -> Option { - let mut cart_positions: HashSet = HashSet::new(); - for cart in self.carts.iter() { - cart_positions.insert(cart.position); + fn run_tick(&mut self, find_final_cart: bool) -> Option { + let mut collided_cart_indices = HashSet::new(); + let mut cart_positions: HashMap = HashMap::new(); + for (index, cart) in self.carts.iter().enumerate() { + cart_positions.insert(cart.position, index); } - for cart in self.carts.iter_mut() { + for (index, cart) in self.carts.iter_mut().enumerate() { + if collided_cart_indices.contains(&index) { + continue; + } + let Vector { x, y } = cart.position; cart_positions.remove(&cart.position); cart.position = match cart.direction { @@ -235,12 +246,27 @@ impl Track { cart.next_turn = (cart.next_turn + 1) % INTER_SEQ.len() as u8; } - if cart_positions.contains(&cart.position) { - return Some(cart.position); + if let Some(colliding_cart) = cart_positions.get(&cart.position) { + if find_final_cart { + collided_cart_indices.insert(index); + collided_cart_indices.insert(*colliding_cart); + cart_positions.remove(&cart.position); + continue; + } else { + return Some(cart.position); + } } - cart_positions.insert(cart.position); + cart_positions.insert(cart.position, index); } + + self.carts = self + .carts + .drain(..) + .enumerate() + .filter(|(i, _)| !collided_cart_indices.contains(i)) + .map(|(_, cart)| cart) + .collect(); self.carts.sort_unstable(); None } @@ -248,10 +274,17 @@ impl Track { fn find_first_collision(&mut self) -> Vector { let mut collision: Option = None; while collision.is_none() { - collision = self.run_tick(); + collision = self.run_tick(false); } collision.unwrap() } + + fn find_last_cart(&mut self) -> &Cart { + while self.carts.len() != 1 { + self.run_tick(true); + } + &self.carts[0] + } } fn read_track(filename: &str) -> Result { @@ -264,6 +297,11 @@ pub fn solve_part1() -> Result { Ok(track.find_first_collision()) } +pub fn solve_part2() -> Result { + let mut track = read_track(INPUT)?; + Ok(track.find_last_cart().position) +} + #[cfg(test)] mod tests { use super::*; @@ -326,7 +364,7 @@ mod tests { track_after.carts[1].direction = Direction::East; track_after.carts[1].next_turn = 1; let mut track = test_track(); - track.run_tick(); + track.run_tick(false); assert_eq!(track, track_after); } diff --git a/src/main.rs b/src/main.rs index 869e657..0f57f7f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,4 +60,6 @@ fn main() { println!("Day 13"); let part1 = day13::solve_part1().unwrap(); println!("{},{}", part1.x, part1.y); + let part2 = day13::solve_part2().unwrap(); + println!("{},{}", part2.x, part2.y); }