Progress on day 12

This commit is contained in:
Timothy Warren 2022-12-20 15:59:23 -05:00
parent d432d855e6
commit 9d8c47a9a1

View File

@ -36,20 +36,123 @@ impl Grid<char> {
#[derive(Debug)] #[derive(Debug)]
struct Pathfinder { struct Pathfinder {
current_elevation: char,
current_idx: usize,
start_idx: usize,
end_idx: usize,
grid: Grid<char>, grid: Grid<char>,
steps: Vec<Direction>, steps: Vec<Direction>,
} }
impl Pathfinder { impl Pathfinder {
pub fn from_file_str(file_str: &str) -> Self { pub fn from_file_str(file_str: &str) -> Self {
Pathfinder { let mut pf = Pathfinder {
current_elevation: 'a',
current_idx: 0,
start_idx: 0,
end_idx: 0,
grid: Grid::from_file_str(file_str), grid: Grid::from_file_str(file_str),
steps: Vec::new(), steps: Vec::new(),
} };
pf.go_to_start();
pf
} }
fn find_start_and_end(&self) -> (usize, usize) { fn find_start_and_end(&self) -> (usize, usize) {
(self.grid.find_pos('S').unwrap(), self.grid.find_pos('E').unwrap()) (self.start_idx, self.end_idx)
}
fn go_to_start(&mut self) {
let start = self.grid.find_pos('S').unwrap();
let end = self.grid.find_pos('E').unwrap();
self.current_idx = start;
self.start_idx = start;
self.end_idx = end;
self.current_elevation = 'a';
self.grid.vec[start] = 'a';
self.grid.vec[end] = 'z';
}
fn get_index_for_move(&self, from: usize, dir: Direction) -> Option<usize> {
let (mut x, mut y) = self.grid.idx_xy(from);
match dir {
Direction::Up => {
if y >= 1 {
y -= 1;
} else {
return None;
}
}
Direction::Down => {
if y < self.grid.num_rows() - 1 {
y += 1;
} else {
return None;
}
}
Direction::Left => {
if x >= 1 {
x -= 1;
} else {
return None;
}
}
Direction::Right => {
if x < self.grid.num_cols() - 1 {
x += 1;
} else {
return None;
}
}
};
Some(self.grid.xy_idx(x, y))
}
fn is_valid_move(&self, start: usize, dir: Direction) -> bool {
if let Some(end) = self.get_index_for_move(start, dir) {
// Is the item within the grid?
let start_char = self.grid.get(start);
let end_char = self.grid.get(end);
if start_char.is_none() || end_char.is_none() {
return false;
}
// Is the elevation change 0 or 1?
let start_char = *start_char.unwrap();
let end_char = *end_char.unwrap();
println!("start, end: {}, {}", start_char, end_char);
let diff = end_char.to_digit(26).unwrap() - start_char.to_digit(26).unwrap();
if diff > 1 || end_char < start_char {
return false;
}
let (start_x, start_y) = self.grid.idx_xy(start);
let (end_x, end_y) = self.grid.idx_xy(end);
let x_diff = usize::abs_diff(end_x, start_x);
let y_diff = usize::abs_diff(end_y, start_y);
// Have we moved 0 or 1 in a cardinal direction?
return match (x_diff, y_diff) {
(0, 0) | (0, 1) | (1,0) => true,
_ => false,
};
};
false
}
fn find_valid_moves(&self, start: usize) -> Vec<usize> {
[Direction::Up, Direction::Down, Direction::Left, Direction::Right]
.into_iter()
.filter(|d| self.is_valid_move(start, *d))
.map(|d| self.get_index_for_move(start, d))
.filter(|m| m.is_some())
.map(|m| m.unwrap())
.collect()
} }
} }
@ -75,4 +178,13 @@ mod tests {
assert_eq!((start, end), (0, 21)); assert_eq!((start, end), (0, 21));
} }
#[test]
fn find_valid_moves() {
let finder = Pathfinder::from_file_str(get_test_data());
let (start, end) = finder.find_start_and_end();
assert_eq!(finder.find_valid_moves(start), vec![8, 1]);
assert_eq!(finder.find_valid_moves(8), vec![16, 9]);
}
} }