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

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

import numpy as np
def determinant(matrix):
    return round(np.linalg.det(matrix))

def determinant(matrix):
    #your code here
    result = 0
    l = len(matrix)

    #base case when length of matrix is 1
    if l == 1:
        return matrix[0][0]

    #base case when length of matrix is 2
    if l == 2:
        return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]

    #for length of matrix > 2
    for j in range(0, l):
        # create a sub matrix to find the determinant
        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))

import numpy as np


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