day13 part 1
This commit is contained in:
116
src/tasks/day13.rs
Normal file
116
src/tasks/day13.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
use crate::utils;
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub fn task1() {
|
||||
let (map, mut carts) = read_input();
|
||||
loop {
|
||||
perform_round(&map, &mut carts);
|
||||
}
|
||||
}
|
||||
|
||||
fn read_input() -> (Vec<Vec<char>>, Vec<Cart>) {
|
||||
let input = utils::read_file("input/day13.txt");
|
||||
let input: Vec<&str> = input.lines().collect();
|
||||
let width = input[0].len();
|
||||
let height = input.len();
|
||||
let mut map = Vec::new();
|
||||
let mut inner_vec = Vec::new();
|
||||
inner_vec.resize(height, ' ');
|
||||
map.resize(width, inner_vec);
|
||||
let mut carts = Vec::new();
|
||||
let tiles = vec!['|', '-', '/', '\\', '+'];
|
||||
for (y, line) in input.iter().enumerate() {
|
||||
for (x, c) in line.chars().enumerate() {
|
||||
if tiles.contains(&c) {
|
||||
map[x][y] = c;
|
||||
} else {
|
||||
if c != ' ' {
|
||||
map[x][y] = match c {
|
||||
'>' => '-',
|
||||
'<' => '-',
|
||||
'^' => '-',
|
||||
'v' => '-',
|
||||
_ => panic!("{} is invalid input char at this point", c),
|
||||
};
|
||||
carts.push(Cart {
|
||||
x,
|
||||
y,
|
||||
direction: c,
|
||||
intersections_visited: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(map, carts)
|
||||
}
|
||||
|
||||
struct Cart {
|
||||
x: usize,
|
||||
y: usize,
|
||||
direction: char,
|
||||
intersections_visited: usize,
|
||||
}
|
||||
|
||||
fn perform_round(map: &Vec<Vec<char>>, carts: &mut Vec<Cart>) {
|
||||
carts.sort_unstable_by(|a, b| {
|
||||
if a.y == b.y {
|
||||
a.x.cmp(&b.x)
|
||||
} else {
|
||||
a.y.cmp(&b.y)
|
||||
}
|
||||
});
|
||||
let mut positions: HashSet<(usize, usize)> =
|
||||
carts.iter().map(|cart| (cart.x, cart.y)).collect();
|
||||
|
||||
for cart in carts {
|
||||
let pos_old = (cart.x, cart.y);
|
||||
match cart.direction {
|
||||
'>' => cart.x += 1,
|
||||
'<' => cart.x -= 1,
|
||||
'^' => cart.y -= 1,
|
||||
'v' => cart.y += 1,
|
||||
c => panic!("invalid direction {}", c),
|
||||
}
|
||||
cart.direction = match (cart.direction, map[cart.x][cart.y]) {
|
||||
('>', '/') => '^',
|
||||
('>', '\\') => 'v',
|
||||
('<', '/') => 'v',
|
||||
('<', '\\') => '^',
|
||||
('^', '/') => '>',
|
||||
('^', '\\') => '<',
|
||||
('v', '/') => '<',
|
||||
('v', '\\') => '>',
|
||||
(direction, '+') => {
|
||||
let new_direction = match cart.intersections_visited % 3 {
|
||||
0 => match direction {
|
||||
'>' => '^',
|
||||
'^' => '<',
|
||||
'<' => 'v',
|
||||
'v' => '>',
|
||||
_ => panic!("Invalid direction"),
|
||||
},
|
||||
1 => direction,
|
||||
2 => match direction {
|
||||
'>' => 'v',
|
||||
'^' => '>',
|
||||
'<' => '^',
|
||||
'v' => '<',
|
||||
_ => panic!("Invalid direction"),
|
||||
},
|
||||
_ => panic!("modulo 3 cannot be larger than 2"),
|
||||
};
|
||||
cart.intersections_visited += 1;
|
||||
new_direction
|
||||
}
|
||||
(_, _) => cart.direction,
|
||||
};
|
||||
if positions.contains(&(cart.x, cart.y)) {
|
||||
panic!("We have a collision at {},{}!", cart.x, cart.y);
|
||||
} else {
|
||||
positions.remove(&pos_old);
|
||||
positions.insert((cart.x, cart.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,3 +8,5 @@ pub mod day07;
|
||||
pub mod day08;
|
||||
pub mod day09;
|
||||
pub mod day10;
|
||||
|
||||
pub mod day13;
|
||||
|
||||
Reference in New Issue
Block a user