diff --git a/src/day_16_1/mod.rs b/src/day_16_1/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..6700167f2cb05ec2000195ad30a27866bfbf9e32 --- /dev/null +++ b/src/day_16_1/mod.rs @@ -0,0 +1,257 @@ +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), + } + } +} diff --git a/src/day_16_2/mod.rs b/src/day_16_2/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..18f740fcff1ea11295bdf43306ee8a2de0bfed45 --- /dev/null +++ b/src/day_16_2/mod.rs @@ -0,0 +1,284 @@ +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), + } + } +} diff --git a/src/main.rs b/src/main.rs index 724f0df5fd2e7943f9ae19f0e98629f4207a941b..95339ad94c4d1fc00dd2f3296341b609322a73e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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); }