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)]
struct Coord {
pub row: i32,
pub col: i32,
pub row: usize,
pub col: usize,
}
pub fn run() {
@ -20,19 +20,19 @@ pub fn run() {
.map(|(col, c)| match c {
'S' => {
start = Coord {
row: r as i32,
col: col as i32,
row: r,
col,
};
0
}
'E' => {
target = Coord {
row: r as i32,
col: col as i32,
row: r,
col,
};
25
}
c => (c as u32) - ('a' as u32),
c => (c as u8) - ('a' as u8),
})
.collect_vec()
})
@ -40,7 +40,7 @@ pub fn run() {
#[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")]
@ -53,8 +53,8 @@ pub fn run() {
.enumerate()
.filter(|(_, vv)| **vv == 0)
.map(|(col, _)| Coord {
row: row as i32,
col: col as i32,
row,
col,
})
.collect_vec()
})
@ -62,12 +62,13 @@ pub fn run() {
let min = starting_points
.iter()
.filter_map(|start| bfs(&map, start.clone(), target.clone()))
.min();
.min()
.unwrap();
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 queue = std::collections::VecDeque::new();
queue.push_back((start, 0));
@ -76,62 +77,53 @@ fn bfs(map: &Vec<Vec<u32>>, start: Coord, target: Coord) -> Option<usize> {
if next == target {
return Some(path_length);
}
let up = Coord {
row: next.row - 1,
col: next.col,
};
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;
match make_coord((next.row as isize) + 1, next.col as isize, &map, &visited) {
Some(down) if map[next.row][next.col] + 1
>= map[down.row][down.col] => {
visited[down.row][down.col] = true;
queue.push_back((down, path_length + 1));
},
_ => {}
}
let can_up = check_bounds(&up, map)
&& !visited[up.row as usize][up.col as usize]
&& map[next.row as usize][next.col as usize] + 1
>= map[up.row as usize][up.col as usize];
if can_up {
visited[up.row as usize][up.col as usize] = true;
match make_coord((next.row as isize) - 1, next.col as isize, &map, &visited) {
Some(up) if map[next.row][next.col] + 1
>= map[up.row][up.col] => {
visited[up.row][up.col] = true;
queue.push_back((up, path_length + 1));
},
_ => {}
}
let can_left = check_bounds(&left, map)
&& !visited[left.row as usize][left.col as usize]
&& map[next.row as usize][next.col as usize] + 1
>= map[left.row as usize][left.col as usize];
if can_left {
visited[left.row as usize][left.col as usize] = true;
match make_coord(next.row as isize, (next.col as isize) - 1, &map, &visited) {
Some(left) if map[next.row][next.col] + 1
>= map[left.row][left.col] => {
visited[left.row][left.col] = true;
queue.push_back((left, path_length + 1));
},
_ => {}
}
let can_right = check_bounds(&right, map)
&& !visited[right.row as usize][right.col as usize]
&& map[next.row as usize][next.col as usize] + 1
>= map[right.row as usize][right.col as usize];
if can_right {
visited[right.row as usize][right.col as usize] = true;
match make_coord(next.row as isize, (next.col as isize) + 1, &map, &visited) {
Some(right) if map[next.row][next.col] + 1
>= map[right.row][right.col] => {
visited[right.row][right.col] = true;
queue.push_back((right, path_length + 1));
},
_ => {}
}
}
None
}
fn check_bounds(coord: &Coord, map: &Vec<Vec<u32>>) -> bool {
coord.row >= 0
&& coord.col >= 0
&& coord.row < map.len() as i32
&& coord.row < map.len() as i32
&& coord.col < map[coord.row as usize].len() as i32
fn make_coord(row: isize, col: isize, map: &Vec<Vec<u8>>, visited: &Vec<Vec<bool>>) -> Option<Coord> {
if row >= 0
&& col >= 0
&& row < map.len() as isize
&& (col as usize) < map[row as usize].len()
&& !visited[row as usize][col as usize] {
Some(Coord {
row: row as usize,
col: col as usize
})
} else {
None
}
}