day 16
This commit is contained in:
195
day16/src/main.rs
Normal file
195
day16/src/main.rs
Normal file
@@ -0,0 +1,195 @@
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Direction {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
Up = 2,
|
||||
Down = 3,
|
||||
}
|
||||
|
||||
const DIRECTION_MASK: [u8; 4] = [1, 2, 4, 8];
|
||||
|
||||
fn pass_light(layout: &Vec<&[u8]>, energized: &mut Vec<Vec<u8>>, mut x: usize, mut y: usize, mut dir: Direction) {
|
||||
loop {
|
||||
let energized_field = &mut energized[y][x];
|
||||
let mask = DIRECTION_MASK[dir as usize];
|
||||
if *energized_field & mask != 0 {
|
||||
return;
|
||||
}
|
||||
*energized_field |= mask;
|
||||
match dir {
|
||||
Direction::Left => {
|
||||
match layout[y][x] {
|
||||
b'/' => {
|
||||
if y < layout.len() - 1 {
|
||||
y += 1;
|
||||
dir = Direction::Down;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'\\' => {
|
||||
if y > 0 {
|
||||
y -= 1;
|
||||
dir = Direction::Up;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'|' => {
|
||||
if y > 0 {
|
||||
pass_light(layout, energized, x, y - 1, Direction::Up);
|
||||
}
|
||||
if y < layout.len() - 1 {
|
||||
pass_light(layout, energized, x, y + 1, Direction::Down);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if x > 0 {
|
||||
x -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Right => {
|
||||
match layout[y][x] {
|
||||
b'/' => {
|
||||
if y > 0 {
|
||||
y -= 1;
|
||||
dir = Direction::Up;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'\\' => {
|
||||
if y < layout.len() - 1 {
|
||||
y += 1;
|
||||
dir = Direction::Down;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'|' => {
|
||||
if y > 0 {
|
||||
pass_light(layout, energized, x, y - 1, Direction::Up);
|
||||
}
|
||||
if y < layout.len() - 1 {
|
||||
pass_light(layout, energized, x, y + 1, Direction::Down);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if x < layout[0].len() - 1 {
|
||||
x += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Up => {
|
||||
match layout[y][x] {
|
||||
b'/' => {
|
||||
if x < layout[0].len() - 1 {
|
||||
x += 1;
|
||||
dir = Direction::Right;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'\\' => {
|
||||
if x > 0 {
|
||||
x -= 1;
|
||||
dir = Direction::Left;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'-' => {
|
||||
if x > 0 {
|
||||
pass_light(layout, energized, x - 1, y, Direction::Left);
|
||||
}
|
||||
if x < layout[0].len() - 1 {
|
||||
pass_light(layout, energized, x + 1, y, Direction::Right);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if y > 0 {
|
||||
y -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Down => {
|
||||
match layout[y][x] {
|
||||
b'/' => {
|
||||
if x > 0 {
|
||||
x -= 1;
|
||||
dir = Direction::Left;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'\\' => {
|
||||
if x < layout[0].len() - 1 {
|
||||
x += 1;
|
||||
dir = Direction::Right;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'-' => {
|
||||
if x > 0 {
|
||||
pass_light(layout, energized, x - 1, y, Direction::Left);
|
||||
}
|
||||
if x < layout[0].len() - 1 {
|
||||
pass_light(layout, energized, x + 1, y, Direction::Right);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if y < layout.len() - 1 {
|
||||
y += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let layout = input_str.lines().map(|str| str.as_bytes()).collect::<Vec<_>>();
|
||||
let mut energized: Vec<Vec<u8>> = vec![vec![0; layout[0].len()]; layout.len()];
|
||||
pass_light(&layout, &mut energized, 0, 0, Direction::Right);
|
||||
let count1 = energized.iter().fold(
|
||||
0, |acc, elem| acc + elem.iter().fold(
|
||||
0, |acc, &elem| acc + (elem > 0) as i32));
|
||||
let count2 =
|
||||
(0..layout.len()).map(|y| (0, y, Direction::Right))
|
||||
.chain((0..layout.len()).map(|y| (layout[0].len() - 1, y, Direction::Left)))
|
||||
.chain((0..layout[0].len()).map(|x| (x, 0, Direction::Down)))
|
||||
.chain((0..layout[0].len()).map(|x| (x, layout.len() - 1, Direction::Up)))
|
||||
.map(|(x, y, dir)| {
|
||||
energized.iter_mut().for_each(|vec| vec.iter_mut().for_each(|x| { *x = 0; }));
|
||||
pass_light(&layout, &mut energized, x, y, dir);
|
||||
energized.iter().fold(
|
||||
0, |acc, elem| acc + elem.iter().fold(
|
||||
0, |acc, &elem| acc + (elem > 0) as i32))
|
||||
}).max().unwrap();
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Energized1: {}", count1);
|
||||
println!("Energized2: {}", count2);
|
||||
}
|
Reference in New Issue
Block a user