Hone logo
Hone
Problems

Navigating the Maze: Obstruction-Free Pathfinding in Go

Imagine you're building a system for autonomous robots or game characters that need to navigate complex environments. A critical aspect of this is finding paths that avoid obstacles. This challenge will test your ability to design efficient Go algorithms for pathfinding in a grid-based environment, ensuring your chosen path is free from any obstructions.

Problem Description

Your task is to implement a Go function that finds the shortest, obstruction-free path between a start point and an end point in a 2D grid. The grid can contain free spaces and obstacles. You need to return the sequence of coordinates representing the path.

Key Requirements:

  • Grid Representation: The grid will be represented as a 2D slice of integers ([][]int), where 0 represents a free space and 1 represents an obstacle.
  • Pathfinding Algorithm: You need to choose and implement a suitable pathfinding algorithm. Common choices include Breadth-First Search (BFS) or A*.
  • Obstruction-Free: The returned path must only consist of free spaces (0) and cannot pass through any obstacles (1).
  • Shortest Path: If multiple valid paths exist, the algorithm should find one of the shortest paths.
  • Return Value: The function should return a slice of [2]int representing the coordinates of the path from start to end, inclusive. If no path exists, return nil.

Expected Behavior:

Given a grid, a start coordinate, and an end coordinate, the function should return a slice of coordinates representing the shortest path. The path should start at the start coordinate and end at the end coordinate.

Edge Cases to Consider:

  • The start or end point is an obstacle.
  • The start and end points are the same.
  • No path exists between the start and end points.
  • The grid is empty or has invalid dimensions.
  • The grid contains only obstacles or only free spaces.

Examples

Example 1:

Input:
grid = [
  [0, 0, 0, 1, 0],
  [0, 1, 0, 0, 0],
  [0, 0, 0, 1, 0],
  [1, 0, 0, 0, 0],
  [0, 0, 0, 0, 0]
]
start = [0, 0]
end = [4, 4]

Output:
[[0,0], [0,1], [0,2], [1,2], [2,2], [2,3], [3,3], [4,3], [4,4]]

Explanation:
This output represents one of the shortest paths from [0,0] to [4,4] without encountering any obstacles (represented by 1s).

Example 2:

Input:
grid = [
  [0, 1, 0],
  [0, 1, 0],
  [0, 0, 0]
]
start = [0, 0]
end = [0, 2]

Output:
nil

Explanation:
The only paths from [0,0] to [0,2] are blocked by obstacles at [0,1] and [1,1].

Example 3:

Input:
grid = [
  [0, 0, 0],
  [0, 0, 0],
  [0, 0, 0]
]
start = [1, 1]
end = [1, 1]

Output:
[[1,1]]

Explanation:
When the start and end points are the same, the path consists only of that single point.

Constraints

  • The grid will have dimensions between 1x1 and 50x50 (inclusive).
  • Grid elements will be either 0 (free space) or 1 (obstacle).
  • Start and end coordinates will be valid indices within the grid.
  • The algorithm should aim for a time complexity that scales reasonably with the grid size, ideally better than brute-force for larger grids.

Notes

  • Consider how you will represent the grid and the path. Go's slices are a natural fit.
  • Think about how to keep track of visited cells to avoid infinite loops.
  • When reconstructing the path, you'll likely need to store parent pointers or similar information during the search.
  • The choice of pathfinding algorithm (BFS, A*) will impact performance and implementation complexity. BFS guarantees the shortest path in an unweighted grid, while A* can be more efficient with a good heuristic.
Loading editor...
go