Write a function that accepts a square matrix (`N x N` 2D array) and returns the determinant of the matrix.

How to take the determinant of a matrix -- it is simplest to start with the smallest cases:

A 1x1 matrix `|a|` has determinant `a`.

A 2x2 matrix `[ [a, b], [c, d] ]` or
```
|a  b|
|c  d|
```
has determinant: `a*d - b*c`.

The determinant of an `n x n` sized matrix is calculated by reducing the problem to the calculation of the determinants of `n` matrices of`n-1 x n-1` size.

For the 3x3 case, `[ [a, b, c], [d, e, f], [g, h, i] ]` or
```
|a b c|  
|d e f|  
|g h i|  
```
the determinant is: `a * det(a_minor) - b * det(b_minor) + c * det(c_minor)` where `det(a_minor)` refers to taking the determinant of the 2x2 matrix created by crossing out the row and column in which the element a occurs:
```
|- - -|
|- e f|
|- h i|  
```
Note the alternation of signs. 

The determinant of larger matrices are calculated analogously, e.g. if M is a 4x4 matrix with first row `[a, b, c, d]`, then:

`det(M) = a * det(a_minor) - b * det(b_minor) + c * det(c_minor) - d * det(d_minor)`

Difficulty: MEDIUM_HARD
Starter code: def determinant(matrix):
	

Solutions:
def determinant(m):
	a = 0
	if len(m) == 1:
		a = m[0][0]
	else:
		for n in xrange(len(m)):
			if (n + 1) % 2 == 0:
				a -= m[0][n] * determinant([o[:n] + o[n + 1:] for o in m[1:]])
			else:
				a += m[0][n] * determinant([o[:n] + o[n + 1:] for o in m[1:]])
	return a


import numpy as np

def determinant(a):
	return round(np.linalg.det(np.matrix(a)))


def determinant(matrix):
	result = 0
	l = len(matrix)
	if l == 1:
		return matrix[0][0]
	if l == 2:
		return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
	for j in range(0, l):
		if l != 2:
			sub_matrix = []
			sub_matrix = [row[0:j] + row[j + 1:] for row in matrix[1:]]
		result = result + (-1) ** j * matrix[0][j] * determinant(sub_matrix)
	return result


def determinant(matrix):
	return reduce(lambda r, i: r + (-1) ** i * matrix[0][i] * determinant([m[:i] + m[i + 1:] for m in matrix[1:]]), range(len(matrix[0])), 0) if len(matrix) != 1 else matrix[0][0]


def sub_determinant(matrix, i):
	sub_matrix = []
	for j in range(1, len(matrix)):
		sub_matrix.append(matrix[j][:i] + matrix[j][i + 1:])
	return sub_matrix

def determinant(matrix):
	if len(matrix) == 0:
		return 0
	elif len(matrix) == 1:
		return matrix[0][0]
	elif len(matrix) == 2:
		return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
	else:
		sum = 0
		for i in range(0, len(matrix)):
			if 1 == i & 1:
				sum = sum - matrix[0][i] * determinant(sub_determinant(matrix, i))
			else:
				sum = sum + matrix[0][i] * determinant(sub_determinant(matrix, i))
		return sum


def determinant(m):
	(ans, sizeM) = (0, len(m))
	if sizeM == 1:
		return m[0][0]
	for n in range(sizeM):
		ans += (-1) ** n * m[0][n] * determinant([m[i][:n] + m[i][n + 1:] for i in range(1, sizeM)])
	return ans


from numpy.linalg import det
determinant = lambda m: int(round(det(m)))


def determinant(m):
	if len(m) == 1:
		return m[0][0]
	if len(m) == 2:
		return m[0][0] * m[1][1] - m[0][1] * m[1][0]
	li = [[m[j][:i] + m[j][i + 1:] for j in range(1, len(m))] for i in range(len(m))]
	return sum((-m[0][i] * determinant(j) if i & 1 else m[0][i] * determinant(j) for (i, j) in enumerate(li)))