From 0f1a695b00d1420913db7d836c0be851c0de4271 Mon Sep 17 00:00:00 2001 From: Rico Hageman Date: Tue, 10 Dec 2024 23:53:41 +0000 Subject: [PATCH] No unsafe code in day 10 --- benches/bench_days.rs | 2 +- src/day10/mod.rs | 128 ++++++++++++++++++++++-------------------- src/day5/mod.rs | 4 +- 3 files changed, 70 insertions(+), 64 deletions(-) diff --git a/benches/bench_days.rs b/benches/bench_days.rs index 12fcf2b..7ad6e5f 100644 --- a/benches/bench_days.rs +++ b/benches/bench_days.rs @@ -38,4 +38,4 @@ macro_rules! benches { }; } -benches!(1, 2, 3, 4, 5, 7, 8, 9, 10); \ No newline at end of file +benches!(1, 2, 3, 4, 5, 7, 8, 9, 10); diff --git a/src/day10/mod.rs b/src/day10/mod.rs index 05747f2..991c693 100644 --- a/src/day10/mod.rs +++ b/src/day10/mod.rs @@ -1,6 +1,6 @@ +use fixedbitset::FixedBitSet; use itertools::*; use std::collections::VecDeque; -use fixedbitset::FixedBitSet; use strum::IntoEnumIterator; use strum_macros::EnumIter; @@ -19,8 +19,48 @@ struct Grid { height: usize, } -static mut QUEUE: VecDeque<(usize, u8)> = VecDeque::new(); -static mut TRAIL_ENDS: FixedBitSet = FixedBitSet::new(); +struct GridFinder { + queue: VecDeque<(usize, u8)>, +} + +impl GridFinder { + pub fn new(grid: &Grid) -> Self { + Self { + queue: VecDeque::with_capacity(grid.width * grid.height), + } + } + + fn find_trails_starting_at( + &mut self, + grid: &Grid, + trail_head: usize, + mut trail_end: impl FnMut(usize), + ) { + self.queue.clear(); + self.queue.push_front((trail_head, 0)); + + while let Some((index, height)) = self.queue.pop_front() { + if height == 9 { + trail_end(index); + continue; + } + + for direction in Direction::iter() { + let Some(next_index) = grid.move_towards(index, direction) else { + continue; + }; + + let next_height = grid.at(next_index); + + if next_height != height + 1 { + continue; + } + + self.queue.push_front((next_index, next_height)); + } + } + } +} impl Grid { fn from_input(input: &str) -> Self { @@ -40,11 +80,6 @@ impl Grid { }) }); - unsafe { - TRAIL_ENDS.grow(width * height); - QUEUE.reserve(width * height); - } - Self { inner, width, @@ -92,67 +127,40 @@ impl Grid { fn trail_heads(&self) -> impl Iterator + use<'_> { self.inner.iter().positions(|height| *height == 0) } - - unsafe fn find_trails_starting_at(&self, trail_head: usize, mut trail_end: impl FnMut(usize)) { - QUEUE.clear(); - QUEUE.push_front((trail_head, 0)); - - while let Some((index, height)) = QUEUE.pop_front() { - if height == 9 { - trail_end(index); - continue; - } - - for direction in Direction::iter() { - let Some(next_index) = self.move_towards(index, direction) else { - continue; - }; - - let next_height = self.at(next_index); - - if next_height != height + 1 { - continue; - } - - QUEUE.push_front((next_index, next_height)); - } - } - } } pub fn part1(input: &str) -> usize { - unsafe { - let grid = Grid::from_input(input); - - grid.trail_heads() - .map(|trail_head| { - TRAIL_ENDS.clear(); - grid.find_trails_starting_at(trail_head, |trail_end| { - TRAIL_ENDS.insert(trail_end); - }); - - TRAIL_ENDS.count_ones(..) - }) - .sum() - } + let grid = Grid::from_input(input); + let mut finder = GridFinder::new(&grid); + let mut trail_ends = FixedBitSet::with_capacity(grid.width * grid.height); + + grid.trail_heads() + .map(|trail_head| { + trail_ends.clear(); + finder.find_trails_starting_at(&grid, trail_head, |trail_end| { + trail_ends.insert(trail_end); + }); + + trail_ends.count_ones(..) + }) + .sum() } pub fn part2(input: &str) -> usize { - unsafe { - let grid = Grid::from_input(input); + let grid = Grid::from_input(input); + let mut finder = GridFinder::new(&grid); - grid.trail_heads() - .map(|trail_head| { - let mut rating = 0; + grid.trail_heads() + .map(|trail_head| { + let mut rating = 0; - grid.find_trails_starting_at(trail_head, |_| { - rating += 1; - }); + finder.find_trails_starting_at(&grid, trail_head, |_| { + rating += 1; + }); - rating - }) - .sum() - } + rating + }) + .sum() } #[cfg(test)] diff --git a/src/day5/mod.rs b/src/day5/mod.rs index 8e8d526..22e24c1 100644 --- a/src/day5/mod.rs +++ b/src/day5/mod.rs @@ -26,9 +26,7 @@ pub struct BitSetIterator { impl BitSetIterator { pub fn new(value: u128) -> Self { - Self { - value, - } + Self { value } } }