diff --git a/16/src/main.rs b/16/src/main.rs index 1054087..6bafcfd 100644 --- a/16/src/main.rs +++ b/16/src/main.rs @@ -47,16 +47,6 @@ impl Display for FromDirection { } } -struct Tile { - kind: char, -} - -impl From for Tile { - fn from(c: char) -> Self { - Tile { kind: c } - } -} - struct Contraption { tiles: Vec>, } @@ -66,8 +56,42 @@ struct VisitState { visited_rays: HashSet<((i64, i64), FromDirection)>, } +impl VisitState { + fn score(&self) -> u64 { + self.energized.iter().flatten().filter(|c| **c).count() as u64 + } + fn dump(&self) { + println!("Score {}:", self.score()); + for line in &self.energized { + println!( + " {}", + String::from_iter(line.iter().map(|b| if *b { '#' } else { '.' })) + ); + } + } +} + + impl Contraption { fn cast_ray<'a>( + &'a mut self, + state: &'a mut VisitState, + pos: (i64, i64), + dir: FromDirection, + ) { + let mut new_rays = self.cast_ray_inner(state, pos, dir); + + loop { + new_rays = new_rays + .iter() + .flat_map(|(pos, dir)| self.cast_ray_inner(state, *pos, *dir)) + .collect(); + if new_rays.len() == 0 { + break; + } + } + } + fn cast_ray_inner<'a>( &'a mut self, state: &'a mut VisitState, mut pos: (i64, i64), @@ -148,42 +172,52 @@ impl From> for Contraption { } } -fn dump_state(state: &Vec>) { - for line in state { - println!( - "{}", - String::from_iter(line.iter().map(|b| if *b { '#' } else { '.' })) - ); - } -} - // PROBLEM 1 solution fn problem1(input: Lines) -> u64 { let mut contraption = Contraption::from(input); let mut state = contraption.empty_state(); - let mut new_rays = contraption.cast_ray(&mut state, (0, 0), FromDirection::Left); - for ray in &new_rays { - println!(" {:?}", ray); - } - - loop { - new_rays = new_rays - .iter() - .flat_map(|(pos, dir)| contraption.cast_ray(&mut state, *pos, *dir)) - .collect(); - if new_rays.len() == 0 { - break; - } - } + contraption.cast_ray(&mut state, (0,0), FromDirection::Left); state.energized.iter().flatten().filter(|c| **c).count() as u64 } // PROBLEM 2 solution fn problem2(input: Lines) -> u64 { - 0 + let mut contraption = Contraption::from(input); + let mut max_tiles = 0u64; + + for y in 0..contraption.tiles.len() as i64 { + let mut left_state = contraption.empty_state(); + contraption.cast_ray(&mut left_state, (0, y), FromDirection::Left); + let mut right_state = contraption.empty_state(); + contraption.cast_ray( + &mut right_state, + (contraption.tiles[0].len() as i64 - 1, y), + FromDirection::Right, + ); + max_tiles = std::cmp::max( + max_tiles, + std::cmp::max(left_state.score(), right_state.score()), + ); + } + for x in 0..contraption.tiles[0].len() as i64 { + let mut top_state = contraption.empty_state(); + contraption.cast_ray(&mut top_state, (x, 0), FromDirection::Above); + let mut bottom_state = contraption.empty_state(); + contraption.cast_ray( + &mut bottom_state, + (x, contraption.tiles.len() as i64 - 1), + FromDirection::Below, + ); + max_tiles = std::cmp::max( + max_tiles, + std::cmp::max(top_state.score(), bottom_state.score()), + ); + } + + max_tiles } #[cfg(test)]