Challenge 38
Rust Challenge: Pathfinding in a Grid
Write a function shortest_path
using BFS to find the shortest path length from the top-left (0,0) to the bottom-right (n-1,m-1) in a 2D grid.
The grid uses 0 for empty spaces and 1 for walls. Move only up, down, left, or right (no diagonals), and don’t pass through walls.
fn shortest_path(grid: Vec<Vec<i32>>) -> Option<usize> { // your implementation goes here // don't touch the code in the main function below } fn main() { // Test 1: Simple 3x3 grid with path let grid1 = vec![ vec![0, 1, 0], vec![0, 1, 0], vec![0, 0, 0], ]; let result1 = shortest_path(grid1); if result1 != Some(4) { panic!("Test 1 failed: Expected Some(4), got {:?}", result1); } println!("Test 1 passed: {:?}", result1); // Test 2: 2x2 grid (from test_shortest_path_5) let grid2 = vec![vec![0, 0], vec![0, 0]]; let result2 = shortest_path(grid2); if result2 != Some(2) { panic!("Test 2 failed: Expected Some(2), got {:?}", result2); } println!("Test 2 passed: {:?}", result2); // Test 3: No path due to walls blocking the way let grid3 = vec![ vec![0, 0, 0], vec![1, 1, 1], vec![0, 0, 0], ]; let result3 = shortest_path(grid3); if result3 != None { panic!("Test 3 failed: Expected None, got {:?}", result3); } println!("Test 3 passed: {:?}", result3); // Test 4: Empty grid let grid4: Vec<Vec<i32>> = vec![]; let result4 = shortest_path(grid4); if result4 != None { panic!("Test 4 failed: Expected None, got {:?}", result4); } println!("Test 4 passed: {:?}", result4); }
Solution
Click to Show/Hide Solution
#![allow(unused)] fn main() { fn shortest_path(grid: Vec<Vec<i32>>) -> Option<usize> { use std::collections::VecDeque; if grid.is_empty() || grid[0].is_empty() { return None; } let rows = grid.len(); let cols = grid[0].len(); // Check if start or end is a wall if grid[0][0] == 1 || grid[rows - 1][cols - 1] == 1 { return None; } let mut queue = VecDeque::new(); let mut visited = vec![vec![false; cols]; rows]; let mut distances = vec![vec![usize::MAX; cols]; rows]; queue.push_back((0, 0)); visited[0][0] = true; distances[0][0] = 0; let directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]; // right, down, left, up while let Some((r, c)) = queue.pop_front() { if r == rows - 1 && c == cols - 1 { return Some(distances[r][c]); } for &(dr, dc) in &directions { let new_r = (r as i32 + dr) as usize; let new_c = (c as i32 + dc) as usize; if new_r < rows && new_c < cols && !visited[new_r][new_c] && grid[new_r][new_c] == 0 { queue.push_back((new_r, new_c)); visited[new_r][new_c] = true; distances[new_r][new_c] = distances[r][c] + 1; } } } None } }