Skip to content

Commit

Permalink
Add problem 1926: Nearest Exit from Entrance in Maze
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Nov 1, 2023
1 parent 242aff3 commit c796773
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,7 @@ pub mod problem_1911_maximum_alternating_subsequence_sum;
pub mod problem_1913_maximum_product_difference_between_two_pairs;
pub mod problem_1915_number_of_wonderful_substrings;
pub mod problem_1920_build_array_from_permutation;
pub mod problem_1926_nearest_exit_from_entrance_in_maze;

#[cfg(test)]
mod test_utilities;
80 changes: 80 additions & 0 deletions src/problem_1926_nearest_exit_from_entrance_in_maze/bfs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::collections::VecDeque;
use std::convert::TryInto;

impl Solution {
pub fn nearest_exit(maze: Vec<Vec<char>>, entrance: Vec<i32>) -> i32 {
let mut maze = maze;
let [y, x]: [_; 2] = entrance.try_into().ok().unwrap();
let y = y as u8;
let x = x as u8;

let mut queue = VecDeque::new();

maze[usize::from(y)][usize::from(x)] = '\0';

for neighbor in [(y.wrapping_sub(1), x), (y, x.wrapping_sub(1)), (y, x + 1), (y + 1, x)] {
if let Some(state) = maze
.get_mut(usize::from(neighbor.0))
.and_then(|row| row.get_mut(usize::from(neighbor.1)))
{
if *state == '.' {
*state = '\0';

queue.push_back(neighbor);
}
}
}

let mut result = 1;

while !queue.is_empty() {
for _ in 0..queue.len() {
let node = queue.pop_front().unwrap();

for neighbor in [
(node.0.wrapping_sub(1), node.1),
(node.0, node.1.wrapping_sub(1)),
(node.0, node.1 + 1),
(node.0 + 1, node.1),
] {
if let Some(state) = maze
.get_mut(usize::from(neighbor.0))
.and_then(|row| row.get_mut(usize::from(neighbor.1)))
{
if *state == '.' {
*state = '\0';

queue.push_back(neighbor);
}
} else {
return result;
}
}
}

result += 1;
}

-1
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn nearest_exit(maze: Vec<Vec<char>>, entrance: Vec<i32>) -> i32 {
Self::nearest_exit(maze, entrance)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
25 changes: 25 additions & 0 deletions src/problem_1926_nearest_exit_from_entrance_in_maze/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pub mod bfs;

pub trait Solution {
fn nearest_exit(maze: Vec<Vec<char>>, entrance: Vec<i32>) -> i32;
}

#[cfg(test)]
mod tests {
use super::Solution;

pub fn run<S: Solution>() {
let test_cases = [
((&["++.+", "...+", "+++."] as &[_], [1, 2]), 1),
((&["+++", "...", "+++"], [1, 0]), 2),
((&[".+"], [0, 0]), -1),
];

for ((maze, entrance), expected) in test_cases {
assert_eq!(
S::nearest_exit(maze.iter().map(|row| row.chars().collect()).collect(), entrance.into()),
expected,
);
}
}
}

0 comments on commit c796773

Please sign in to comment.