Skip to content
Snippets Groups Projects
Commit abcfc3a1 authored by Falk Rehse's avatar Falk Rehse
Browse files

Day 16

parent 726c9763
No related branches found
No related tags found
No related merge requests found
use std::collections::HashMap;
use crate::util::*;
pub fn solve_from_str(input: &str) -> u32 {
let grid = to_grid(input);
let mut energized = HashMap::new();
follow_beam(0, 0, Direction::Right, &grid, &mut energized);
energized.iter().map(|_| 1).sum()
}
fn follow_beam(
x: i32,
y: i32,
direction: Direction,
grid: &Vec<Vec<char>>,
energized: &mut HashMap<(i32, i32), Vec<Direction>>,
) {
if x < 0 || x >= grid.len() as i32 {
return;
}
if y < 0 || y >= grid[0].len() as i32 {
return;
}
if let Some(directions) = energized.get_mut(&(x, y)) {
if directions.contains(&direction) {
return;
} else {
directions.push(direction);
}
} else {
energized.insert((x, y), vec![direction]);
}
match grid[x as usize][y as usize] {
'.' => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
'/' => match direction {
Direction::Up => {
let direction = Direction::Right;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Down => {
let direction = Direction::Left;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Left => {
let direction = Direction::Down;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Right => {
let direction = Direction::Up;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
},
'\\' => match direction {
Direction::Up => {
let direction = Direction::Left;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Down => {
let direction = Direction::Right;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Left => {
let direction = Direction::Up;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Right => {
let direction = Direction::Down;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
},
'-' => match direction {
Direction::Up => {
let direction = Direction::Left;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
let direction = Direction::Right;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Down => {
let direction = Direction::Left;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
let direction = Direction::Right;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Left => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
Direction::Right => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
},
'|' => match direction {
Direction::Up => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
Direction::Down => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
Direction::Left => {
let direction = Direction::Up;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
let direction = Direction::Down;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Right => {
let direction = Direction::Up;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
let direction = Direction::Down;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
},
_ => panic!(),
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Direction {
Up,
Down,
Left,
Right,
}
impl Direction {
fn to_vec(&self) -> (i32, i32) {
match self {
Direction::Up => (0, -1),
Direction::Down => (0, 1),
Direction::Left => (-1, 0),
Direction::Right => (1, 0),
}
}
}
use std::collections::HashMap;
use crate::util::*;
pub fn solve_from_str(input: &str) -> u32 {
let grid = to_grid(input);
let mut max = 0;
for x in 0..grid.len() as i32 {
let mut energized = HashMap::new();
follow_beam(x, 0, Direction::Down, &grid, &mut energized);
max = u32::max(max, energized.iter().map(|_| 1).sum());
}
for x in 0..grid.len() as i32 {
let mut energized = HashMap::new();
follow_beam(x, grid[0].len() as i32 - 1, Direction::Up, &grid, &mut energized);
max = u32::max(max, energized.iter().map(|_| 1).sum());
}
for y in 0..grid[0].len() as i32 {
let mut energized = HashMap::new();
follow_beam(0, y, Direction::Right, &grid, &mut energized);
max = u32::max(max, energized.iter().map(|_| 1).sum());
}
for y in 0..grid[0].len() as i32 {
let mut energized = HashMap::new();
follow_beam(grid.len() as i32 - 1, y, Direction::Left, &grid, &mut energized);
max = u32::max(max, energized.iter().map(|_| 1).sum());
}
max
}
fn follow_beam(
x: i32,
y: i32,
direction: Direction,
grid: &Vec<Vec<char>>,
energized: &mut HashMap<(i32, i32), Vec<Direction>>,
) {
if x < 0 || x >= grid.len() as i32 {
return;
}
if y < 0 || y >= grid[0].len() as i32 {
return;
}
if let Some(directions) = energized.get_mut(&(x, y)) {
if directions.contains(&direction) {
return;
} else {
directions.push(direction);
}
} else {
energized.insert((x, y), vec![direction]);
}
match grid[x as usize][y as usize] {
'.' => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
'/' => match direction {
Direction::Up => {
let direction = Direction::Right;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Down => {
let direction = Direction::Left;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Left => {
let direction = Direction::Down;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Right => {
let direction = Direction::Up;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
},
'\\' => match direction {
Direction::Up => {
let direction = Direction::Left;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Down => {
let direction = Direction::Right;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Left => {
let direction = Direction::Up;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Right => {
let direction = Direction::Down;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
},
'-' => match direction {
Direction::Up => {
let direction = Direction::Left;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
let direction = Direction::Right;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Down => {
let direction = Direction::Left;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
let direction = Direction::Right;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Left => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
Direction::Right => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
},
'|' => match direction {
Direction::Up => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
Direction::Down => follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
),
Direction::Left => {
let direction = Direction::Up;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
let direction = Direction::Down;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
Direction::Right => {
let direction = Direction::Up;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
let direction = Direction::Down;
follow_beam(
x + direction.to_vec().0,
y + direction.to_vec().1,
direction,
grid,
energized,
);
}
},
_ => panic!(),
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Direction {
Up,
Down,
Left,
Right,
}
impl Direction {
fn to_vec(&self) -> (i32, i32) {
match self {
Direction::Up => (0, -1),
Direction::Down => (0, 1),
Direction::Left => (-1, 0),
Direction::Right => (1, 0),
}
}
}
......@@ -7,8 +7,11 @@ mod day_12_2;
mod day_13_1;
mod day_13_2;
mod day_14_1;
mod day_14_2;
mod day_15_1;
mod day_15_2;
mod day_16_1;
mod day_16_2;
mod day_1_1;
mod day_1_2;
mod day_2_1;
......@@ -35,7 +38,7 @@ use std::fs;
fn main() {
let input = fs::read_to_string("input").expect("Could not read input!");
let solution = day_12_2::solve_from_str(input.trim_end());
let solution = day_16_2::solve_from_str(input.trim_end());
println!("Solution: {}", solution);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment