grid: improve ergonomics with more trait impls and other improvements
update puzzles to pass tests, some performance gains
This commit is contained in:
18
src/day10.rs
18
src/day10.rs
@ -1,19 +1,19 @@
|
||||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
use grid::Grid;
|
||||
use itertools::Itertools;
|
||||
use std::io::{BufRead, Lines};
|
||||
use std::io::BufRead;
|
||||
|
||||
#[aoc_generator(day10)]
|
||||
pub fn get_input(input: &[u8]) -> TrailMap {
|
||||
TrailMap::from(input.lines())
|
||||
TrailMap::from(input)
|
||||
}
|
||||
|
||||
pub struct TrailMap {
|
||||
map: Grid<u8>,
|
||||
}
|
||||
|
||||
impl<T: BufRead> From<Lines<T>> for TrailMap {
|
||||
fn from(input: Lines<T>) -> Self {
|
||||
impl<T: BufRead> From<T> for TrailMap {
|
||||
fn from(input: T) -> Self {
|
||||
Self { map: input.into() }
|
||||
}
|
||||
}
|
||||
@ -29,13 +29,13 @@ impl TrailMap {
|
||||
.collect_vec()
|
||||
}
|
||||
fn count_reachable_from(&self, pos: &(i64, i64), needle: u8, visited: &mut Grid<bool>) -> u64 {
|
||||
if visited.get(pos) == Some(true) {
|
||||
if visited.get(pos) == Some(&true) {
|
||||
return 0;
|
||||
} else {
|
||||
visited.set(pos, true);
|
||||
}
|
||||
let our_val = self.map.get(pos).unwrap();
|
||||
if our_val == needle {
|
||||
if *our_val == needle {
|
||||
return 1;
|
||||
}
|
||||
// adjacents that are +1
|
||||
@ -43,7 +43,7 @@ impl TrailMap {
|
||||
.iter()
|
||||
.map(|(x_ofs, y_ofs)| (pos.0 + x_ofs, pos.1 + y_ofs)) // get target position
|
||||
.map(|target_pos| (target_pos, self.map.get(&target_pos))) // get value at that position
|
||||
.filter(|(_, val)| *val == Some(our_val + 1)) // only interested if it's our value + 1
|
||||
.filter(|(_, val)| *val == Some(&(our_val + 1))) // only interested if it's our value + 1
|
||||
.map(|(pos, _)| pos) // discard the value
|
||||
.map(|pos| self.count_reachable_from(&pos, needle, visited))
|
||||
.sum()
|
||||
@ -51,14 +51,14 @@ impl TrailMap {
|
||||
|
||||
fn count_paths_to(&self, pos: &(i64, i64), needle: u8) -> u64 {
|
||||
let our_val = self.map.get(pos).unwrap();
|
||||
if our_val == needle {
|
||||
if *our_val == needle {
|
||||
return 1;
|
||||
}
|
||||
[(-1, 0), (1, 0), (0, -1), (0, 1)] // left, right, up, down
|
||||
.iter()
|
||||
.map(|(x_ofs, y_ofs)| (pos.0 + x_ofs, pos.1 + y_ofs)) // get target position
|
||||
.map(|target_pos| (target_pos, self.map.get(&target_pos))) // get value at that position
|
||||
.filter(|(_, val)| *val == Some(our_val + 1)) // only interested if it's our value + 1
|
||||
.filter(|(_, val)| *val == Some(&(our_val + 1))) // only interested if it's our value + 1
|
||||
.map(|(pos, _)| pos) // discard the value
|
||||
.map(|mov| self.count_paths_to(&mov, needle))
|
||||
.sum::<u64>()
|
||||
|
Reference in New Issue
Block a user