From cfa7060a0b9ddbed3ca0f90bc8cc9fb3a555bac5 Mon Sep 17 00:00:00 2001 From: Mathis Date: Sun, 24 Dec 2023 17:01:44 +0100 Subject: [PATCH] 2023-16: Implement part two --- .../day_16_the_floor_will_be_lava/mod.rs | 6 +- .../day_16_the_floor_will_be_lava/part_two.rs | 132 ++++++++++++++++++ 2 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 src/year_2023/day_16_the_floor_will_be_lava/part_two.rs diff --git a/src/year_2023/day_16_the_floor_will_be_lava/mod.rs b/src/year_2023/day_16_the_floor_will_be_lava/mod.rs index 4336cd9..322e9eb 100644 --- a/src/year_2023/day_16_the_floor_will_be_lava/mod.rs +++ b/src/year_2023/day_16_the_floor_will_be_lava/mod.rs @@ -1,5 +1,5 @@ pub mod part_one; -// pub mod part_two; +pub mod part_two; pub mod common; use crate::utils::solution::Solution; @@ -19,7 +19,7 @@ impl Solution for DaySolution { } fn part_two(&self) -> String { - // input_reader::read_input_file(self.input_path(), part_two::part_two) - String::from("Not implemented") + input_reader::read_input_file(self.input_path(), part_two::part_two) + // String::from("Not implemented") } } \ No newline at end of file diff --git a/src/year_2023/day_16_the_floor_will_be_lava/part_two.rs b/src/year_2023/day_16_the_floor_will_be_lava/part_two.rs new file mode 100644 index 0000000..056885a --- /dev/null +++ b/src/year_2023/day_16_the_floor_will_be_lava/part_two.rs @@ -0,0 +1,132 @@ +use std::collections::HashSet; + +use super::common::{Contraption, Direction}; + +pub fn part_two(input_lines: Vec) -> String { + + let mut contraption: Vec> = Vec::new(); + for line in input_lines { + let mut row: Vec = Vec::new(); + for c in line.chars() { + match c { + '.' => row.push(Contraption::Empty), + '\\' => row.push(Contraption::MirrorLeft), + '/' => row.push(Contraption::MirrorRight), + '|' => row.push(Contraption::SplitterVert), + '-' => row.push(Contraption::SplitterHoriz), + _ => panic!("Unknown character: {}", c), + } + } + contraption.push(row); + } + + let mut max_energy = 0; + + let mut start_stack: Vec<(i32, i32, Direction)> = Vec::new(); + + for i in 0..contraption.len() { + start_stack.push((i as i32, 0, Direction::Right)); + start_stack.push((i as i32, contraption[0].len() as i32 - 1, Direction::Left)); + } + + for j in 0..contraption[0].len() { + start_stack.push((0, j as i32, Direction::Down)); + start_stack.push((contraption.len() as i32 - 1, j as i32, Direction::Up)); + + } + + while let Some((start_i, start_j, start_direction)) = start_stack.pop() { + + // print_contraption(&contraption); + let mut energized: Vec> = vec![vec![false; contraption[0].len()]; contraption.len()]; + let mut memory: HashSet<(i32, i32, Direction)> = HashSet::new(); + let mut stack: Vec<(i32, i32, Direction)> = Vec::new(); + stack.push((start_i, start_j, start_direction)); + + while let Some((i, j, direction)) = stack.pop() { + + if i >= contraption[0].len() as i32 || j >= contraption.len() as i32 || i < 0 || j < 0 { + continue; + } + + if memory.contains(&(i, j, direction)) { + continue; + } else { + memory.insert((i, j, direction)); + } + + energized[i as usize][j as usize] = true; + + let tile = &contraption[i as usize][j as usize]; + // println!("{} {}: {:?} - {:?}", i, j, direction, tile); + + match (tile, direction) { + (Contraption::Empty, Direction::Right) => { + stack.push((i, j+1, Direction::Right)); + }, + (Contraption::Empty, Direction::Left) => { + stack.push((i, j-1, Direction::Left)); + }, + (Contraption::Empty, Direction::Up) => { + stack.push((i-1, j, Direction::Up)); + }, + (Contraption::Empty, Direction::Down) => { + stack.push((i+1, j, Direction::Down)); + }, + (Contraption::MirrorLeft, Direction::Right) => { + stack.push((i+1, j, Direction::Down)); + } + (Contraption::MirrorLeft, Direction::Left) => { + stack.push((i-1, j, Direction::Up)); + }, + (Contraption::MirrorLeft, Direction::Up) => { + stack.push((i, j-1, Direction::Left)); + }, + (Contraption::MirrorLeft, Direction::Down) => { + stack.push((i, j+1, Direction::Right)); + }, + (Contraption::MirrorRight, Direction::Right) => { + stack.push((i-1, j, Direction::Up)); + }, + (Contraption::MirrorRight, Direction::Left) => { + stack.push((i+1, j, Direction::Down)); + }, + (Contraption::MirrorRight, Direction::Up) => { + stack.push((i, j+1, Direction::Right)); + }, + (Contraption::MirrorRight, Direction::Down) => { + stack.push((i, j-1, Direction::Left)); + }, + (Contraption::SplitterVert, Direction::Right | Direction::Left) => { + stack.push((i-1, j, Direction::Up)); + stack.push((i+1, j, Direction::Down)); + }, + (Contraption::SplitterVert, Direction::Down) => { + stack.push((i+1, j, Direction::Down)); + }, + (Contraption::SplitterVert, Direction::Up) => { + stack.push((i-1, j, Direction::Up)); + }, + (Contraption::SplitterHoriz, Direction::Up | Direction::Down) => { + stack.push((i, j-1, Direction::Left)); + stack.push((i, j+1, Direction::Right)); + }, + (Contraption::SplitterHoriz, Direction::Left) => { + stack.push((i, j-1, Direction::Left)); + }, + (Contraption::SplitterHoriz, Direction::Right) => { + stack.push((i, j+1, Direction::Right)); + } + } + } + + // print_energized(&energized); + + let energized_count = energized.iter().flatten().filter(|x| **x).count(); + if energized_count > max_energy { + max_energy = energized_count; + } + } + + max_energy.to_string() +} \ No newline at end of file