This kata is the second part of a series: [Neighbourhood kata collection](https://www.codewars.com/collections/5b2f4db591c746349d0000ce). If this one is to easy you can try out the harder Katas.;)

___
The neighbourhood of a cell (in a matrix) are cells that are near to it. There are two popular types:
- The [Moore neighborhood](https://en.wikipedia.org/wiki/Moore_neighborhood) are eight cells which surround a given cell.
- The [Von Neumann neighborhood](https://en.wikipedia.org/wiki/Von_Neumann_neighborhood) are four cells which share a border with the given cell.

___

# Task
Given a neighbourhood type (`"moore"` or `"von_neumann"`), a 2D matrix (a list of lists) and a pair of coordinates, return the list of neighbours of the given cell.

Notes:
- The order of the elements in the output list is not important. 
- If the input indexes are outside the matrix, return an empty list.
- If the the matrix is empty, return an empty list.
- Order of the indices: The first index should be applied for the outer/first matrix layer. The last index for the most inner/last layer. `coordinates = (m, n)` should be apllied like `mat[m][n]`

___

## Examples
```
\ n   0    1    2    3    4
m  --------------------------
0  |  0 |  1 |  2 |  3 |  4 |
1  |  5 |  6 |  7 |  8 |  9 |
2  | 10 | 11 | 12 | 13 | 14 |
3  | 15 | 16 | 17 | 18 | 19 |
4  | 20 | 21 | 22 | 23 | 24 |
   --------------------------

get_neighborhood("moore", mat, (1,1)) == [0, 1, 2, 5, 7, 10, 11, 12]
get_neighborhood("moore", mat, (0,0)) == [1, 6, 5]
get_neighborhood("moore", mat, (4,2)) == [21, 16, 17, 18, 23]
get_neighborhood("von_neumann", mat, (1,1)) == [1, 5, 7, 11]
get_neighborhood("von_neumann", mat, (0,0)) == [1, 5]
get_neighborhood("von_neumann", mat, (4,2)) == [21, 17, 23]
```
___

Translations are appreciated.^^

If you like chess take a look at [Chess Aesthetics](https://www.codewars.com/kata/5b574980578c6a6bac0000dc)

If you like puzzles and take a look at [Rubik's cube](https://www.codewars.com/kata/5b3bec086be5d8893000002e)

Difficulty: introductory

Starter code:

def get_neighbourhood(n_type, mat, coordinates):
	

Solutions:
def get_neighbourhood(typ, arr, coordinates):
    
    def isInside(x,y): return 0 <= x < len(arr) and 0 <= y < len(arr[0])
    
    x,y = coordinates
    if not isInside(x,y): return []
    
    neigh = ( [(dx, dy) for dx in range(-1,2) for dy in range(-1,2) if (dx,dy) != (0,0)]
                  if typ == 'moore' else [(0,1), (0,-1), (1,0), (-1,0)] )
    
    return [ arr[a][b] for a,b in ((x+dx,y+dy) for dx,dy in neigh) if isInside(a,b) ]

vn = [(-1, 0), (0, -1), (0, 1), (1, 0)]
mr = vn + [(-1, -1), (-1, 1), (1, -1), (1, 1)]

def get_neighbourhood(nh, a, p):
    h, w, nh, x, y = list(range(len(a))), list(range(len(a[0] if a else []))), mr if "r" in nh else vn, *p
    return [a[x+i][y+j] for i, j in nh if ((x+i) in h and (y+j) in w)] if x in h and y in w else []


def get_neighbourhood(n_type, matrix, coordinates):
    height = len(matrix)
    width = len(matrix[0])
    y, x = coordinates
    if not (0 <= y < height and 0 <= x < width): return []
    moore = [(y+dy, x+dx) for dy in [-1, 0, 1] for dx in [-1, 0, 1] if (dy, dx) != (0, 0)]
    von_neumann = [moore[idx] for idx in (1, 3, 4, 6)]
    neighbors_coords = eval(n_type)
    neighbors = [matrix[y][x] for y, x in neighbors_coords if 0 <= y < height and 0 <= x < width]
    return neighbors

D = {"von_neumann":((0, 1), (0, -1), (1, 0), (-1, 0)),
     "moore":((0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1))}

def get_neighbourhood(n_type, mat, coordinates):
    (i, j), H, W = coordinates, len(mat), len(mat[0])
    check = lambda a,b: 0 <= i+a < H and 0 <= j+b < W
    return [mat[i+k][j+l] for k,l in D[n_type] if check(k, l)] if check(0, 0) else []

def get_neighbourhood(type_, arr, co):
    h, w = len(arr), len(arr[0])
    i, j = co
    if not arr[0] or i>=h or j>=w:return []
    li = []
    if type_ == 'moore':
        return [arr[k][l] for k in range(i-1 if i>0 else 0, (i+1 if i<h-1 else h-1) + 1)
                          for l in range(j-1 if j>0 else 0,(j+1 if j<w-1 else w-1)+1) if [k,l]!=[i,j]]
    else:
        li = [arr[i-1][j] if i>0 else 'x',
              arr[i+1][j] if i<h-1 else 'x',
              arr[i][j-1] if j>0 else 'x', 
              arr[i][j+1] if j<w-1 else 'x']
        while 'x' in li : li.remove('x')
        return li

NEIGHBOURHOOD = {"von_neumann": 1, "moore": 2}

def closer_cells(n, x, y):
    return ((x+u, y+v)
            for u in range(-1, 2) for v in range(-1, 2)
            if 0 < abs(u) + abs(v) <= n)

def get_neighbourhood(n_type, arr, coordinates):
    def is_inside(x, y):
        return 0 <= x < len(arr) and 0 <= y < len(arr[0])

    return [] if not is_inside(*coordinates) else [arr[x][y]
        for x, y in closer_cells(NEIGHBOURHOOD[n_type], *coordinates)
        if is_inside(x, y)]

def get_neighbourhood(n_type, mat, coord):
    x, y = coord[0], coord[1]
    if x<0 or y<0 or x>=len(mat) or y>=len(mat[0]):
        return []
    val = [(x-1, y), (x, y-1), (x, y+1), (x+1, y)]
    if n_type == 'moore':
        val += [(x-1, y-1), (x-1, y+1), (x+1, y-1), (x+1, y+1)]
    return [mat[a[0]][a[1]] for a in val if a[0]>=0 and a[0]<len(mat) and a[1]>=0 and a[1]<len(mat[0])]


def get_offsets(distance, moore=True):
    offsets = list(range(-distance, distance + 1))
    for dr in offsets:
        for dc in offsets:
            if (dr, dc) == (0, 0):
                continue
            if not moore and abs(dr) + abs(dc) > distance:
                # Manhattan distance too large
                continue
            yield (dr, dc)

def get_neighbourhood(n_type, arr, coordinates, distance=1):
    h, w = len(arr), len(arr[0])
    if not (0 <= coordinates[0] < h and 0 <= coordinates[1] < w):
        # Coordinate not in arr
        return []
    r, c = coordinates
    return [
        arr[r + dr][c + dc]
        for dr, dc in get_offsets(distance, n_type == 'moore')
        if 0 <= r + dr < h and 0 <= c + dc < w
    ]


def get_neighbourhood(n_type, mat, coordinates):
    d = {'moore': [(0,1),(1,0),(-1,0),(0,-1),(-1,1),(1,-1),(1,1),(-1,-1)],
         'von_neumann': [(0,1),(1,0),(-1,0),(0,-1)]
    }
    y,x = coordinates
    if not mat or not 0<=y<len(mat) or not 0<=x<len(mat[0]): return []
    
    r = []
    for i,j in d.get(n_type):
        a,b = y+i,x+j
        if 0<=a<len(mat) and 0<=b<len(mat[0]):
            r.append(mat[a][b])
    
    return r