~~~if-not:java
You have to code a function **getAllPrimeFactors** wich take an integer as parameter and return an array containing its prime decomposition by ascending factors, if a factors appears multiple time in the decomposition it should appear as many time in the array. 

exemple: `getAllPrimeFactors(100)` returns `[2,2,5,5]` in this order. 

This decomposition may not be the most practical. 

You should also write **getUniquePrimeFactorsWithCount**, a function which will return an array containing two arrays: one with prime numbers appearing in the decomposition and the other containing their respective power. 

exemple: `getUniquePrimeFactorsWithCount(100)` returns `[[2,5],[2,2]]`

You should also write **getUniquePrimeFactorsWithProducts** an array containing the prime factors to their respective powers. 

exemple: `getUniquePrimeFactorsWithProducts(100)` returns `[4,25]`
~~~
~~~if:java
You have to code a function **getAllPrimeFactors** wich take an integer as parameter and return an array containing its prime decomposition by ascending factors, if a factors appears multiple time in the decomposition it should appear as many time in the array. 

exemple: `getAllPrimeFactors(100)` returns `[2,2,5,5]` in this order. 

This decomposition may not be the most practical. 

You should also write **getUniquePrimeFactorsWithCount**, a function which will return an array containing two arrays: one with prime numbers appearing in the decomposition and the other containing their respective power. 

exemple: `getUniquePrimeFactorsWithCount(100)` returns `[[2,5],[2,2]]`

You should also write **getPrimeFactorPotencies** an array containing the prime factors to their respective powers. 

exemple: `getPrimeFactorPotencies(100)` returns `[4,25]`
~~~

Errors, if:

* `n` is not a number
* `n` not an integer 
* `n` is negative or 0 

The three functions should respectively return `[]`,  `[[],[]]` and `[]`. 

Edge cases: 

* if `n=0`, the function should respectively return `[]`, `[[],[]]` and  `[]`.
* if `n=1`, the function should respectively return `[1]`, `[[1],[1]]`, `[1]`.
* if `n=2`, the function should respectively return `[2]`, `[[2],[1]]`, `[2]`.

The result for `n=2` is normal. The result for `n=1` is arbitrary and has been chosen to return a usefull result. The result for `n=0` is also arbitrary 
but can not be chosen to be both usefull and intuitive. (`[[0],[0]]` would be meaningfull but wont work for general use of decomposition, `[[0],[1]]` would work but is not intuitive.)

Difficulty: EASY
Tags: Fundamentals

Starter code:
def getAllPrimeFactors(n):
	

Solutions:
def getAllPrimeFactors(n):
	if n == 0:
		return []
	elif n == 1:
		return [1]
	elif type(n) != int:
		return errora
	elif n < 0:
		return errora
	allfacts = []
	current = 2
	n_copy = n
	while current <= n:
		if n_copy % current == 0:
			allfacts.append(current)
			n_copy /= current
		else:
			current += 1
	return allfacts

def getUniquePrimeFactorsWithCount(n):
	if type(n) != int:
		return errorb
	elif n < 0:
		return errorb
	primes = []
	power = []
	listA = getAllPrimeFactors(n)
	for i in range(len(listA)):
		if listA[i] not in primes:
			primes.append(listA[i])
			power.append(1)
		else:
			power[-1] += 1
	return [primes, power]

def getUniquePrimeFactorsWithProducts(n):
	if type(n) != int:
		return errorc
	elif n < 0:
		return errorc
	listlist = getUniquePrimeFactorsWithCount(n)
	listc = []
	for i in range(len(listlist[0])):
		listc.append(listlist[0][i] ** listlist[1][i])
	return listc
errora = []
errorb = [[], []]
errorc = []


from collections import Counter

def getAllPrimeFactors(n):
	if type(n) != int:
		return []
	(li, j) = ([], 2)
	while j * j <= n:
		if n % j:
			j += 1
			continue
		li.append(j)
		n //= j
	return li + [[n], []][n < 1]

def getUniquePrimeFactorsWithCount(n):
	r = Counter(getAllPrimeFactors(n))
	return [list(r.keys()), list(r.values())]
getUniquePrimeFactorsWithProducts = lambda n: [i ** j for (i, j) in zip(*getUniquePrimeFactorsWithCount(n))]


from collections import defaultdict
from functools import lru_cache
from itertools import chain

@lru_cache(maxsize=None)
def factors(n):
	if n == 1:
		return [(1, 1)]
	(res, wheel) = (defaultdict(int), [1, 2, 2, 4, 2, 4, 2, 4, 6, 2, 6])
	(x, y) = (2, 0)
	while x * x <= n:
		if not n % x:
			res[x] += 1
			n //= x
		else:
			x += wheel[y]
			y = 3 if y == 10 else y + 1
	res[n] += 1
	return res.items()

def getAllPrimeFactors(n):
	return list(chain.from_iterable(([k] * v for (k, v) in factors(n)))) if isinstance(n, int) and n > 0 else []

def getUniquePrimeFactorsWithCount(n):
	return list(map(list, zip(*factors(n)))) if isinstance(n, int) and n > 0 else [[], []]

def getUniquePrimeFactorsWithProducts(n):
	return [k ** v for (k, v) in factors(n)] if isinstance(n, int) and n > 0 else []


def getAllPrimeFactors(n):
	result = []
	if isinstance(n, int) and n > 0:
		if n == 1:
			result = [1]
		number = 2
		while n > 1:
			print(n)
			if not n % number:
				result.append(number)
				n /= number
				number = 2
			else:
				number += 1
	return result

def getUniquePrimeFactorsWithCount(n):
	pf = getAllPrimeFactors(n)
	r1 = []
	r2 = []
	if pf:
		r1 = list(set(pf))
		r2 = [pf.count(x) for x in r1]
	return [r1, r2]

def getUniquePrimeFactorsWithProducts(n):
	return [x ** y for (x, y) in zip(*getUniquePrimeFactorsWithCount(n))]


import math
import collections

def getAllPrimeFactors(n):
	if isinstance(n, int) and n > -1:
		if n != 1:
			(listy, m, x) = ([], n, True)
			while x:
				for i in range(2, int(math.sqrt(n)) + 1):
					if n % i == 0:
						n = n // i
						listy.append(i)
						break
				else:
					x = False
			if m > 1:
				listy.append(n)
			return listy
		else:
			return [1]
	else:
		return []

def getUniquePrimeFactorsWithCount(n):
	if isinstance(n, int) and n > -1:
		if n != 1:
			(listy, m, x) = ([], n, True)
			while x:
				for i in range(2, int(math.sqrt(n)) + 1):
					if n % i == 0:
						n = n // i
						listy.append(i)
						break
				else:
					x = False
			if m > 1:
				listy.append(n)
		else:
			listy = [1]
	else:
		listy = []
	fancy_dict = collections.Counter()
	resulty_list = [[], []]
	for number in listy:
		fancy_dict[number] += 1
	for (key, value) in list(fancy_dict.items()):
		resulty_list[0].append(key)
		resulty_list[1].append(value)
	return resulty_list

def getUniquePrimeFactorsWithProducts(n):
	if isinstance(n, int) and n > -1:
		if n != 1:
			(listy, m, x) = ([], n, True)
			while x:
				for i in range(2, int(math.sqrt(n)) + 1):
					if n % i == 0:
						n = n // i
						listy.append(i)
						break
				else:
					x = False
			if m > 1:
				listy.append(n)
		else:
			listy = [1]
	else:
		listy = []
	fancy_dict = collections.Counter()
	resulty_list = [[], []]
	for number in listy:
		fancy_dict[number] += 1
	for (key, value) in list(fancy_dict.items()):
		resulty_list[0].append(key)
		resulty_list[1].append(value)
	return [resulty_list[0][i] ** resulty_list[1][i] for i in range(len(resulty_list[0]))]


LIMIT = 10 ** 6
sieve = [True] * (LIMIT // 2)
for i in range(3, int(LIMIT ** 0.5) + 1, 2):
	if sieve[i // 2]:
		sieve[i * i // 2::i] = [False] * ((LIMIT - i * i - 1) // 2 // i + 1)
PRIMES = [2] + [2 * i + 1 for i in range(1, LIMIT // 2) if sieve[i]]
from collections import Counter

def getAllPrimeFactors(n):
	if not type(n) == int or n < 1:
		return []
	if n in (1, 2):
		return [n]
	factors = []
	for p in PRIMES:
		if p * p > n:
			break
		while n % p == 0:
			n //= p
			factors.append(p)
	return factors + [n] * (n > 1)

def getUniquePrimeFactorsWithCount(n):
	factors = Counter(getAllPrimeFactors(n))
	return [list(factors.keys()), list(factors.values())]

def getUniquePrimeFactorsWithProducts(n):
	factors = Counter(getAllPrimeFactors(n))
	return [p ** e for (p, e) in factors.items()]


from collections import Counter

def getAllPrimeFactors(n):
	if n == 1:
		return [1]
	(lst, p, n) = ([], 2, 1 if not isinstance(n, int) or n < 0 else n)
	while n > 1:
		while not n % p:
			lst.append(p)
			n //= p
		p += 1 + (p != 2)
	return lst

def getUniquePrimeFactorsWithCount(n):
	return list(map(list, zip(*Counter(getAllPrimeFactors(n)).items()))) or [[], []]

def getUniquePrimeFactorsWithProducts(n):
	return [k ** v for (k, v) in Counter(getAllPrimeFactors(n)).items()]


def getAllPrimeFactors(n):
	if not type(n) is int:
		n = 0
	elif n < 0:
		n = 0
	results = []
	number = 2
	while number < n:
		if not n % number:
			n /= number
			results.append(number)
			number = 2
		else:
			number += 1
	if n:
		results.append(int(n))
	return results

def getUniquePrimeFactorsWithCount(n):
	results = getAllPrimeFactors(n)
	counted = [[], []]
	if not results == []:
		for i in range(results[-1] + 1):
			if i in results:
				counted[0].append(i)
				counted[1].append(results.count(i))
	return counted

def getUniquePrimeFactorsWithProducts(n):
	counted = getUniquePrimeFactorsWithCount(n)
	products = []
	if not counted == [[], []]:
		for i in range(len(counted[0])):
			products.append(counted[0][i] ** counted[1][i])
	return products


def getAllPrimeFactors(n):
	if type(n) is not int or n < 1:
		return []
	elif n < 3:
		return [n]
	factors = []
	while n > 1:
		for i in range(2, n + 1):
			if is_prime(i) and (not n % i):
				factors.append(i)
				n = int(n / i)
				break
	return factors

def getUniquePrimeFactorsWithCount(n):
	f = getAllPrimeFactors(n)
	factors = list(set(f))
	powers = [f.count(factor) for factor in factors]
	return [factors, powers]

def getUniquePrimeFactorsWithProducts(n):
	cf = getUniquePrimeFactorsWithCount(n)
	return [factor ** count for (factor, count) in zip(cf[0], cf[1])]

def is_prime(n):
	for i in range(2, n):
		if not n % i:
			return False
	return True