refactor coord checking
This commit is contained in:
parent
e40e06510b
commit
1c41e885ad
108
src/day12/mod.rs
108
src/day12/mod.rs
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user