All challenges
Medium 0 solved 0% acceptance

A* Search on a Weighted Grid

Find the cheapest path across a grid of terrain costs with A*, the search algorithm behind game and robot pathfinding.

What you'll learn

  • Find the cheapest path with a priority queue
  • Use the Manhattan distance as a heuristic
  • Understand why admissible heuristics stay optimal

Problem

A* is the classic pathfinding algorithm of games and robotics. It explores cells in order of f = g + h, where g is the cost paid so far and h is a heuristic estimate of the cost still to go.

The grid holds a cost for every cell: entering a cell costs its value, and 0 means a wall that cannot be entered. You start on start (its cost is not paid) and may move up, down, left or right.

Use A* with the Manhattan distance |row - goal_row| + |col - goal_col| as the heuristic. Every open cell costs at least 1, so this heuristic never overestimates and A* returns an optimal answer.

Implement a_star_cost(grid, start, goal).

Input

grid: A matrix of cell costs (0 = wall).

start, goal: [row, col] positions.

Output

Return the minimum total cost to reach goal, or -1 if it cannot be reached (including when start or goal is a wall).

Constraints

1 ≤ rows, cols ≤ 100

0 ≤ each cost ≤ 9

Examples

Example 1
Input:
goal = [2, 2]
grid = [
    [1, 1, 1],
    [1, 0, 1],
    [1, 1, 1]
]
start = [0, 0]

Expected output:
expected = 4
Input:
std::vector<long long> goal = {2, 2};
std::vector<std::vector<long long>> grid = {
    {1, 1, 1},
    {1, 0, 1},
    {1, 1, 1}
};
std::vector<long long> start = {0, 0};

Expected output:
long long expected = 4;
Input:
long[] goal = new long[] {2, 2};
long[][] grid = new long[][] {
    new long[] {1, 1, 1},
    new long[] {1, 0, 1},
    new long[] {1, 1, 1}
};
long[] start = new long[] {0, 0};

Expected output:
long expected = 4;

Explanation

The centre is a wall. Going right twice and down twice (or down then right) enters 4 cells of cost 1: total 4.

Example 2
Input:
goal = [0, 2]
grid = [
    [1, 9, 1],
    [1, 9, 1],
    [1, 1, 1]
]
start = [0, 0]

Expected output:
expected = 6
Input:
std::vector<long long> goal = {0, 2};
std::vector<std::vector<long long>> grid = {
    {1, 9, 1},
    {1, 9, 1},
    {1, 1, 1}
};
std::vector<long long> start = {0, 0};

Expected output:
long long expected = 6;
Input:
long[] goal = new long[] {0, 2};
long[][] grid = new long[][] {
    new long[] {1, 9, 1},
    new long[] {1, 9, 1},
    new long[] {1, 1, 1}
};
long[] start = new long[] {0, 0};

Expected output:
long expected = 6;

Explanation

Crossing the 9 directly costs 9 + 1 = 10. Going down, along the bottom row and back up enters six cells of cost 1: total 6.

References

This challenge is adapted for CodeUtility. Follow the statement and constraints above.

Learn from others

Community solutions

No published solutions yet. Solve this challenge to share the first one.