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)

Source: codewars | Difficulty: EASY
Tags: Matrices

Data structures

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:
				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):
		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