From cfd9b4f2ad1a09bedf7f764f84448a61faab54a3 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 20:26:02 +0200 Subject: Refile for merging repos --- 2018/src/bin/day_13.rs | 249 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 2018/src/bin/day_13.rs (limited to '2018/src/bin/day_13.rs') diff --git a/2018/src/bin/day_13.rs b/2018/src/bin/day_13.rs new file mode 100644 index 0000000..005f216 --- /dev/null +++ b/2018/src/bin/day_13.rs @@ -0,0 +1,249 @@ +extern crate advent_of_code_2018; +use advent_of_code_2018::*; + +use std::error::Error; +use std::path::PathBuf; + +// cargo watch -cs "cargo run --release --bin day_13" + +#[derive(Debug)] +enum Road { + LeftRight, + UpDown, + LeftUpRightDown, + RightUpLeftDown, + Intersection, + None +} + +#[derive(Debug)] +struct Cart { + next_turn: TurnDirection, + facing: FacingDirection, + x: usize, + y: usize, + crashed: bool + +} + +#[derive(Debug, Clone, Copy)] +enum FacingDirection { + Up, + Down, + Left, + Right +} + +#[derive(Debug, Clone, Copy)] +enum TurnDirection { + Left, + Straight, + Right +} + +impl TurnDirection { + fn next(&self) -> TurnDirection { + use TurnDirection::*; + + match *self { + Left => Straight, + Straight => Right, + Right => Left + } + } + + fn rotate(&self, facing: &FacingDirection) -> FacingDirection { + match *self { + TurnDirection::Left => match *facing { + FacingDirection::Up => FacingDirection::Left, + FacingDirection::Left => FacingDirection::Down, + FacingDirection::Down => FacingDirection::Right, + FacingDirection::Right => FacingDirection::Up + }, + TurnDirection::Right => match *facing { + FacingDirection::Up => FacingDirection::Right, + FacingDirection::Left => FacingDirection::Up, + FacingDirection::Down => FacingDirection::Left, + FacingDirection::Right => FacingDirection::Down + }, + TurnDirection::Straight => facing.clone() + } + } +} + + + +fn main() -> Result<(), Box> { + let input = read_file(&PathBuf::from("inputs/13.txt"))?; + +// for i in &input { +// println!("{}", i); +// } + + let mut map: Vec> = Vec::new(); + let mut carts: Vec = Vec::new(); + + for (y, line) in input.iter().enumerate() { + let mut map_row = Vec::new(); + for (x, c) in line.chars().enumerate() { + let tile = match c { + ' ' => Road::None, + '-' => Road::LeftRight, + '|' => Road::UpDown, + '/' => Road::LeftUpRightDown, + '\\' => Road::RightUpLeftDown, + '+' => Road::Intersection, + '^' => { + carts.push(Cart { + next_turn: TurnDirection::Left, + facing: FacingDirection::Up, + x: x, + y: y, + crashed: false + }); + Road::UpDown + }, + '<' => { + carts.push(Cart { + next_turn: TurnDirection::Left, + facing: FacingDirection::Left, + x: x, + y: y, + crashed: false + }); + Road::LeftRight + }, + 'v' => { + carts.push(Cart { + next_turn: TurnDirection::Left, + facing: FacingDirection::Down, + x: x, + y: y, + crashed: false + }); + Road::UpDown + }, + '>' => { + carts.push(Cart { + next_turn: TurnDirection::Left, + facing: FacingDirection::Right, + x: x, + y: y, + crashed: false + }); + Road::LeftRight + }, + + _ => { + panic!("Unknown character {}", c); + } + }; + map_row.push(tile); + } + map.push(map_row); + } + + while carts.len() > 1 { + carts.sort_unstable_by(|a, b| a.y.cmp(&b.y).then(a.x.cmp(&b.x))); + + for i in 0..carts.len() { + { + let mut cart = &mut carts[i]; + let road = &map[cart.y][cart.x]; + + match (road, cart.facing, cart.next_turn) { + (Road::LeftRight, FacingDirection::Left, _) => { + cart.x -= 1; + }, + (Road::LeftRight, FacingDirection::Right, _) => { + cart.x += 1; + }, + (Road::LeftRight, _, _) => { + panic!("Sideways cart heading left-right"); + }, + + (Road::UpDown, FacingDirection::Up, _) => { + cart.y -= 1; + }, + (Road::UpDown, FacingDirection::Down, _) => { + cart.y += 1; + }, + (Road::UpDown, _, _) => { + panic!("Sideways cart heading up-down"); + }, + + // / + (Road::LeftUpRightDown, FacingDirection::Down, _) => { + cart.x -= 1; + cart.facing = FacingDirection::Left; + }, + (Road::LeftUpRightDown, FacingDirection::Right, _) => { + cart.y -= 1; + cart.facing = FacingDirection::Up; + }, + (Road::LeftUpRightDown, FacingDirection::Left, _) => { + cart.y += 1; + cart.facing = FacingDirection::Down; + }, + (Road::LeftUpRightDown, FacingDirection::Up, _) => { + cart.x += 1; + cart.facing = FacingDirection::Right; + }, + + // \ + (Road::RightUpLeftDown, FacingDirection::Up, _) => { + cart.x -= 1; + cart.facing = FacingDirection::Left; + }, + (Road::RightUpLeftDown, FacingDirection::Left, _) => { + cart.y -= 1; + cart.facing = FacingDirection::Up; + }, + (Road::RightUpLeftDown, FacingDirection::Right, _) => { + cart.y += 1; + cart.facing = FacingDirection::Down; + }, + (Road::RightUpLeftDown, FacingDirection::Down, _) => { + cart.x += 1; + cart.facing = FacingDirection::Right; + }, + + (Road::Intersection, f, d) => { + cart.facing = d.rotate(&f); + cart.next_turn = d.next(); + match cart.facing { + FacingDirection::Up => { cart.y -= 1 }, + FacingDirection::Down => { cart.y += 1 }, + FacingDirection::Left => { cart.x -= 1 }, + FacingDirection::Right => { cart.x += 1 }, + } + }, + + (Road::None, _, _) => { + panic!("Offroad cart!"); + } + + } + + } + + let collisions = carts.iter() + .enumerate() + .filter(|(other_i, other)| *other_i != i && other.x == carts[i].x && other.y == carts[i].y) + .map(|(other_i, _)| other_i) + .collect::>(); + for other_i in collisions { + let crash_location = (carts[i].x, carts[i].y); + debug!(crash_location); + carts[i].crashed = true; + carts[other_i].crashed = true; + } + } + + carts.retain(|cart| !cart.crashed); + } + + debug!(carts); + + Ok(()) +} -- cgit v1.2.3