---
id: 6a0dcd03ee4e68698080ef6b
title: "Challenge 307: Zoning Regulations"
challengeType: 28
dashedName: challenge-307
---

# --description--

Given a 2D grid (array of arrays) representing a city's building layout, return the coordinates of all buildings that are violating zoning rules.

Each cell in the grid contains one of the labels from the table below. A building is in violation if any of its (up to) 4 neighbors, horizontal or vertical, are a type it cannot be adjacent to.

| Label | Type | Cannot be adjacent to |
| - | - | - |
| `"i"` | industrial | `"R"`, `"I"` |
| `"A"` | Agricultural | `"C"` |
| `"R"` | Residential | `"i"`, `"C"` |
| `"I"` | Institutional | `"i"` |
| `"C"` | Commercial | `"R"`, `"A"` |
| `""` (empty string) | undeveloped | no restrictions |

Return the coordinates of all violating cells as an array of `[row, col]` pairs, in any order. If no violations exist, return an empty array.

# --hints--

`getZoneViolations([["R", "C"], ["", "C"]])` should return `[[0, 0], [0, 1]]`.

```js
assert.deepEqual(getZoneViolations([["R", "C"], ["", "C"]]).sort(), [[0, 0], [0, 1]]);
```

`getZoneViolations([["", "i"], ["", "R"], ["R", "I"]])` should return `[[0, 1], [1, 1]]`.

```js
assert.deepEqual(getZoneViolations([["", "i"], ["", "R"], ["R", "I"]]).sort(), [[0, 1], [1, 1]]);
```

`getZoneViolations([["A", "i", "C"], ["A", "", "C"], ["R", "R", "I"]])` should return `[]`.

```js
assert.deepEqual(getZoneViolations([["A", "i", "C"], ["A", "", "C"], ["R", "R", "I"]]).sort(), []);
```

`getZoneViolations([["R", "R", "C", "R", "R"], ["R", "I", "C", "", "A"], ["R", "R", "", "i", "A"]])` should return `[[0, 1], [0, 2], [0, 3]]`.

```js
assert.deepEqual(getZoneViolations([["R", "R", "C", "R", "R"], ["R", "I", "C", "", "A"], ["R", "R", "", "i", "A"]]).sort(), [[0, 1], [0, 2], [0, 3]]);
```


`getZoneViolations([["R", "A", "A", "", "i", "i"], ["R", "I", "", "C", "i", "i"], ["R", "", "C", "C", "A", "A"], ["R", "R", "C", "I", "R", "R"]])` should return `[[2, 3], [2, 4], [3, 1], [3, 2]]`.

```js
assert.deepEqual(getZoneViolations([["R", "A", "A", "", "i", "i"], ["R", "I", "", "C", "i", "i"], ["R", "", "C", "C", "A", "A"], ["R", "R", "C", "I", "R", "R"]]).sort(), [[2, 3], [2, 4], [3, 1], [3, 2]]);
```

# --seed--

## --seed-contents--

```js
function getZoneViolations(grid) {

  return grid;
}
```

# --solutions--

```js
function getZoneViolations(grid) {
  const rules = {
    "i": ["R", "I"],
    "A": ["C"],
    "R": ["i", "C"],
    "I": ["i"],
    "C": ["R", "A"],
    "": []
  };

  const directions = [[-1, 0], [0, -1], [0, 1], [1, 0]];
  const violations = [];

  for (let row = 0; row < grid.length; row++) {
    for (let col = 0; col < grid[row].length; col++) {
      const cell = grid[row][col];
      const forbidden = rules[cell];

      for (const [dr, dc] of directions) {
        const nr = row + dr;
        const nc = col + dc;
        if (nr >= 0 && nr < grid.length && nc >= 0 && nc < grid[row].length) {
          if (forbidden.includes(grid[nr][nc])) {
            violations.push([row, col]);
            break;
          }
        }
      }
    }
  }

  return violations;
}
```
