Completed day 13 part 2

This commit is contained in:
Tyler Hallada 2019-08-13 00:06:04 -04:00
parent 4b2a232f11
commit 3872264523
2 changed files with 51 additions and 11 deletions

View File

@ -48,6 +48,12 @@ struct Track {
intersections: HashSet<Vector>,
}
#[derive(Debug, PartialEq)]
struct Collision {
position: Vector,
cart_indices: (usize, usize),
}
impl FromStr for Track {
type Err = Box<Error>;
@ -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<Vector> {
let mut cart_positions: HashSet<Vector> = HashSet::new();
for cart in self.carts.iter() {
cart_positions.insert(cart.position);
fn run_tick(&mut self, find_final_cart: bool) -> Option<Vector> {
let mut collided_cart_indices = HashSet::new();
let mut cart_positions: HashMap<Vector, usize> = HashMap::new();
for (index, cart) in self.carts.iter().enumerate() {
cart_positions.insert(cart.position, index);
}
for (index, cart) in self.carts.iter_mut().enumerate() {
if collided_cart_indices.contains(&index) {
continue;
}
for cart in self.carts.iter_mut() {
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) {
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<Vector> = 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<Track> {
@ -264,6 +297,11 @@ pub fn solve_part1() -> Result<Vector> {
Ok(track.find_first_collision())
}
pub fn solve_part2() -> Result<Vector> {
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);
}

View File

@ -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);
}