refactor coord checking

This commit is contained in:
max.nuding 2022-12-12 13:35:34 +01:00
parent e40e06510b
commit 1c41e885ad
Failed to extract signature

View File

@ -3,8 +3,8 @@ use itertools::Itertools;
#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)] #[derive(Debug, PartialEq, Eq, Clone, Hash, Default)]
struct Coord { struct Coord {
pub row: i32, pub row: usize,
pub col: i32, pub col: usize,
} }
pub fn run() { pub fn run() {
@ -20,19 +20,19 @@ pub fn run() {
.map(|(col, c)| match c { .map(|(col, c)| match c {
'S' => { 'S' => {
start = Coord { start = Coord {
row: r as i32, row: r,
col: col as i32, col,
}; };
0 0
} }
'E' => { 'E' => {
target = Coord { target = Coord {
row: r as i32, row: r,
col: col as i32, col,
}; };
25 25
} }
c => (c as u32) - ('a' as u32), c => (c as u8) - ('a' as u8),
}) })
.collect_vec() .collect_vec()
}) })
@ -40,7 +40,7 @@ pub fn run() {
#[cfg(feature = "part1")] #[cfg(feature = "part1")]
{ {
println!("Day 12, Part 01: {:?}", bfs(&map, start, target.clone())); println!("Day 12, Part 01: {:?}", bfs(&map, start, target.clone()).unwrap());
} }
#[cfg(feature = "part2")] #[cfg(feature = "part2")]
@ -53,8 +53,8 @@ pub fn run() {
.enumerate() .enumerate()
.filter(|(_, vv)| **vv == 0) .filter(|(_, vv)| **vv == 0)
.map(|(col, _)| Coord { .map(|(col, _)| Coord {
row: row as i32, row,
col: col as i32, col,
}) })
.collect_vec() .collect_vec()
}) })
@ -62,12 +62,13 @@ pub fn run() {
let min = starting_points let min = starting_points
.iter() .iter()
.filter_map(|start| bfs(&map, start.clone(), target.clone())) .filter_map(|start| bfs(&map, start.clone(), target.clone()))
.min(); .min()
.unwrap();
println!("Day 12, Part 02: {:?}", min); println!("Day 12, Part 02: {:?}", min);
} }
} }
fn bfs(map: &Vec<Vec<u32>>, start: Coord, target: Coord) -> Option<usize> { fn bfs(map: &Vec<Vec<u8>>, start: Coord, target: Coord) -> Option<usize> {
let mut visited = vec![vec![false; map[0].len()]; map.len()]; let mut visited = vec![vec![false; map[0].len()]; map.len()];
let mut queue = std::collections::VecDeque::new(); let mut queue = std::collections::VecDeque::new();
queue.push_back((start, 0)); queue.push_back((start, 0));
@ -76,62 +77,53 @@ fn bfs(map: &Vec<Vec<u32>>, start: Coord, target: Coord) -> Option<usize> {
if next == target { if next == target {
return Some(path_length); return Some(path_length);
} }
let up = Coord { match make_coord((next.row as isize) + 1, next.col as isize, &map, &visited) {
row: next.row - 1, Some(down) if map[next.row][next.col] + 1
col: next.col, >= map[down.row][down.col] => {
}; visited[down.row][down.col] = true;
let down = Coord {
row: next.row + 1,
col: next.col,
};
let left = Coord {
row: next.row,
col: next.col - 1,
};
let right = Coord {
row: next.row,
col: next.col + 1,
};
let can_down = check_bounds(&down, map)
&& !visited[down.row as usize][down.col as usize]
&& map[next.row as usize][next.col as usize] + 1
>= map[down.row as usize][down.col as usize];
if can_down {
visited[down.row as usize][down.col as usize] = true;
queue.push_back((down, path_length + 1)); queue.push_back((down, path_length + 1));
},
_ => {}
} }
let can_up = check_bounds(&up, map) match make_coord((next.row as isize) - 1, next.col as isize, &map, &visited) {
&& !visited[up.row as usize][up.col as usize] Some(up) if map[next.row][next.col] + 1
&& map[next.row as usize][next.col as usize] + 1 >= map[up.row][up.col] => {
>= map[up.row as usize][up.col as usize]; visited[up.row][up.col] = true;
if can_up {
visited[up.row as usize][up.col as usize] = true;
queue.push_back((up, path_length + 1)); queue.push_back((up, path_length + 1));
},
_ => {}
} }
let can_left = check_bounds(&left, map) match make_coord(next.row as isize, (next.col as isize) - 1, &map, &visited) {
&& !visited[left.row as usize][left.col as usize] Some(left) if map[next.row][next.col] + 1
&& map[next.row as usize][next.col as usize] + 1 >= map[left.row][left.col] => {
>= map[left.row as usize][left.col as usize]; visited[left.row][left.col] = true;
if can_left {
visited[left.row as usize][left.col as usize] = true;
queue.push_back((left, path_length + 1)); queue.push_back((left, path_length + 1));
},
_ => {}
} }
let can_right = check_bounds(&right, map) match make_coord(next.row as isize, (next.col as isize) + 1, &map, &visited) {
&& !visited[right.row as usize][right.col as usize] Some(right) if map[next.row][next.col] + 1
&& map[next.row as usize][next.col as usize] + 1 >= map[right.row][right.col] => {
>= map[right.row as usize][right.col as usize]; visited[right.row][right.col] = true;
if can_right {
visited[right.row as usize][right.col as usize] = true;
queue.push_back((right, path_length + 1)); queue.push_back((right, path_length + 1));
},
_ => {}
} }
} }
None None
} }
fn check_bounds(coord: &Coord, map: &Vec<Vec<u32>>) -> bool { fn make_coord(row: isize, col: isize, map: &Vec<Vec<u8>>, visited: &Vec<Vec<bool>>) -> Option<Coord> {
coord.row >= 0 if row >= 0
&& coord.col >= 0 && col >= 0
&& coord.row < map.len() as i32 && row < map.len() as isize
&& coord.row < map.len() as i32 && (col as usize) < map[row as usize].len()
&& coord.col < map[coord.row as usize].len() as i32 && !visited[row as usize][col as usize] {
Some(Coord {
row: row as usize,
col: col as usize
})
} else {
None
}
} }