'How to exclude coordinates which overflow matrix

The task is to write a function that returns all its neighbors for an element. Diagonal elements are not considered neighbors.

In general, the problem is solved, but if the elements fall outside the matrix, the compiler generates runtime error: index out of range [-1] . Now I'm thinking of making a condition that excludes data outside the matrix. Can you tell me how such a condition would look like? I've already tried something like: if element = -1, then remove element from response. But it doesn't work.

package main

import "fmt"

func Input(y, x int) []int {
    matrix := [][]int{
        []int{0, 2, 3},
        []int{2, 3, 1},
        []int{8, 7, 4},
        []int{3, 2, 1},
    }
    k := []int{matrix[y+1][x], matrix[y-1][x], matrix[y][x+1], matrix[y][x-1]}
    for _, z := range k {
        if z == -1 { //error
            return append(k[z:], k[:z-1]...)
        }
    }
    return k
}
func main() {
    fmt.Println(Input(0, 0))
}


Solution 1:[1]

Both x and y indices of neighbors may be out of range, and not just when being -1, but also when they are >= length of the slice you index with them.

So basically there are 4 neighbors:

(y-1,x), (y+1, x), (y,x-1), (y,x+1)

You have to check all out of bounds cases. Your panic happens on the k := ... line, not inside the for loop. Also returning early in the loop will not handle all elements, and that for is wrong from its roots.

So basically this is how you could do it:

var result []int

if y > 0 {
    result = append(result, matrix[y-1][x])
}
if y < len(matrix)-1 {
    result = append(result, matrix[y+1][x])
}
if x > 0 {
    result = append(result, matrix[y][x-1])
}
if x < len(matrix[y])-1 {
    result = append(result, matrix[y][x+1])
}

return result

This will output (try it on the Go Playground):

[2 2]

Note that if x or y is already invalid, the above code will still panic. If you want to protect against it, you also have to validate x and y, e.g.:

var result []int
if y < 0 || y >= len(matrix) || x < 0 || x >= len(matrix[y]) {
    return result
}

Another approach is to list the deltaY and deltaX indices of neighbors in another slice:

var neighbors = [][]int{
    {-1, 0},
    {1, 0},
    {0, -1},
    {0, 1},
}

And you may use a loop to iterate over neighbors, and then you can check indices in a single place:

var result []int
for _, neighbor := range neighbors {
    iy, ix := y+neighbor[0], x+neighbor[1]
    if iy < 0 || iy >= len(matrix) || ix < 0 || ix >= len(matrix[iy]) {
        continue
    }
    result = append(result, matrix[iy][ix])
}

return result

Try this one on the Go Playground.

Note that this second solution also returns neighbors if you specify indices outside of the matrix if the neighbor of that element falls inside the matrix. E.g. using y=-1, x=0 as the input, the neighbor (y+1,x) being 0 will be returned.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1