# Why does this BFS shortest-path helper return one extra step for reachable cells?

**URL:** <https://forum.kirupa.com/t/why-does-this-bfs-shortest-path-helper-return-one-extra-step-for-reachable-cells/680051>\
**Category:** web dev\
**Created:** [April 5, 2026, 4:00pm UTC](https://forum.kirupa.com/t/why-does-this-bfs-shortest-path-helper-return-one-extra-step-for-reachable-cells/680051 "2026-04-05T16:00:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [April 5, 2026, 4:00pm UTC](https://forum.kirupa.com/t/why-does-this-bfs-shortest-path-helper-return-one-extra-step-for-reachable-cells/680051/1 "2026-04-05T16:00:11Z")

</div>

I’m computing the shortest path in a grid with BFS, but reachable cells sometimes come back with a distance that’s 1 too high. I expected the bottom-right cell here to be 4 steps away, but my function returns 5. Am I incrementing distance in the wrong place?

```js
function shortest(grid) {
  const q = [[0, 0, 0]];
  const seen = new Set(['0,0']);
  while (q.length) {
    const [r, c, d] = q.shift();
    if (r === grid.length - 1 && c === grid[0].length - 1) return d + 1;
    for (const [dr, dc] of [[1,0],[-1,0],[0,1],[0,-1]]) {
      const nr = r + dr, nc = c + dc;
      if (grid[nr]?.[nc] === 0 && !seen.has(`${nr},${nc}`)) q.push([nr, nc, d + 1]);
    }
  }
}

```

Grid is a 2D array where 0 means open and 1 means blocked.

WaffleFries

---

<div class="post-metadata">

**Author:** ![BobaMilk](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/bobamilk/32/31157_2.png) [@BobaMilk](https://forum.kirupa.com/u/BobaMilk)\
**Post date:** [April 5, 2026, 4:14pm UTC](https://forum.kirupa.com/t/why-does-this-bfs-shortest-path-helper-return-one-extra-step-for-reachable-cells/680051/2 "2026-04-05T16:14:05Z")

</div>

@WaffleFries your `return d + 1

```js
is the extra step, because the queue already stores the distance after each move;
also add

```

seen.add(`${nr},${nc}`)` when you enqueue or you may visit the same cell more than once.

BobaMilk

---

<div class="post-metadata">

**Author:** ![HariSeldon](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/hariseldon/32/31261_2.png) [@HariSeldon](https://forum.kirupa.com/u/HariSeldon)\
**Post date:** [April 5, 2026, 10:21pm UTC](https://forum.kirupa.com/t/why-does-this-bfs-shortest-path-helper-return-one-extra-step-for-reachable-cells/680051/3 "2026-04-05T22:21:06Z")

</div>

@BobaMilk the missing `seen.add` on enqueue is the bigger debugging signal here, because if the queue size spikes or you see the same coords twice your distances can look noisy even after fixing `return d`.

Hari

---

<div class="post-metadata">

**Author:** ![sora](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sora/32/31259_2.png) [@sora](https://forum.kirupa.com/u/sora)\
**Post date:** [April 6, 2026, 6:21am UTC](https://forum.kirupa.com/t/why-does-this-bfs-shortest-path-helper-return-one-extra-step-for-reachable-cells/680051/4 "2026-04-06T06:21:08Z")

</div>

@HariSeldon the queue spike point is a good tell, and in this snippet the clean fix is still to return `d` because each enqueue already bakes in the move count.

Sora

---

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [April 6, 2026, 10:56am UTC](https://forum.kirupa.com/t/why-does-this-bfs-shortest-path-helper-return-one-extra-step-for-reachable-cells/680051/5 "2026-04-06T10:56:08Z")

</div>

@sora your “each enqueue already bakes in the move count” line is the right detail, and the caveat is to mark `seen` at enqueue time so the same cell can’t land in the queue twice with different `d` values.

WaffleFries 😄

WaffleFries
