The factorial of a number, `n!`, is defined for whole numbers as the product of all integers from `1` to `n`. 

For example, `5!` is `5 * 4 * 3 * 2 * 1 = 120`

Most factorial implementations use a recursive function to determine the value of `factorial(n)`. However, this blows up the stack for large values of `n` - most systems cannot handle stack depths much greater than 2000 levels.

Write an implementation to calculate the factorial of arbitrarily large numbers, *without recursion.*

# Rules

* `n < 0` should return `nil`/  `None`
* `n = 0` should return `1`
* `n > 0` should return `n!`

# Note

Codewars limits the amount of data it will send back and forth, which may introduce a false ceiling for how high of a value of `n` it will accept. All tests use values less than this limit.

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Starter code: def factorial(n):
	

Solutions:
import math

def factorial(n):
	if n >= 0:
		return math.factorial(n)


import math

def factorial(n):
	return math.factorial(n) if n >= 0 else None


def factorial(n):
	if n < 0:
		return None
	ret = 1
	for i in range(2, n + 1):
		ret *= i
	return ret


factorial = lambda _: __import__('math').factorial(_) if _ >= 0 else None


from math import factorial as fact

def factorial(n):
	if n >= 0:
		return fact(n)


from math import factorial as f

def factorial(n):
	if n < 0:
		return None
	elif n == 0:
		return 1
	return f(n)


import math

def factorial(n):
	if n < 0:
		return None
	if n == 0 or n == 1:
		return 1
	if n > 0:
		return math.factorial(n)


from functools import reduce

def factorial(n):
	if n < 0:
		return None
	if n < 2:
		return 1
	return reduce(lambda x, y: x * y, range(1, n + 1))


def factorial(n):
	if n >= 0:
		fact = 1
		for i in range(2, n + 1):
			fact *= i
		return fact
	else:
		return None