Every number may be factored in prime factors.

For example, the number 18 may be factored by its prime factors ``` 2 ``` and ```3```
```
18 = 2 . 3 . 3 = 2 . 3²
```
The sum of the prime factors of 18 is  ```2 + 3 + 3 = 8```

But some numbers like 70 are divisible by the sum of its prime factors:
```
70 = 2 . 5 . 7 # sum of prime factors = 2 + 5 + 7 = 14
and 70 is a multiple of 14
```
Of course that primes would fulfill this property, but is obvious, because the prime decomposition of a number, is the number itself and every number is divisible by iself. That is why we will discard every prime number in the results

We are interested in collect the integer positive numbers (non primes) that have this property in a certain range ```[a, b]``` (inclusive).

Make the function ```mult_primefactor_sum()```, that receives the values ```a```, ```b``` as limits of the range ```[a, b]``` and ```a < b``` and outputs the sorted list of these numbers.

Let's see some cases:
```python
mult_primefactor_sum(10, 100) == [16, 27, 30, 60, 70, 72, 84] 

mult_primefactor_sum(1, 60) == [1, 4, 16, 27, 30, 60]
```

Source: codewars | Difficulty: EASY

Starter code: def mult_primefactor_sum(a, b):
	

Solutions:
def mult_primefactor_sum(a, b):
	s = []
	for i in range(a, b + 1):
		r = factorize_add(i)
		if r != i and i % r == 0:
			s.append(i)
	return s

def factorize_add(num):
	if num < 4:
		return num
	d = 2
	p = 0
	while d < num ** 0.5 + 1:
		while not num % d:
			p += d
			num /= d
		d += 1 if d == 2 else 2
	return p if num == 1 else p + num


def mult_primefactor_sum(a, b):
	ret = []
	for m in range(a, b + 1):
		(p, s, n) = (2, 0, m)
		while n > 1 and p <= n ** 0.5:
			while n % p == 0:
				s += p
				n //= p
			p += 1
		s += n > 1 and n
		if s < m and m % s == 0:
			ret.append(m)
	return ret


from bisect import bisect_left, bisect_right

def spf(n):
	result = 0
	nd = 0
	while n % 2 == 0:
		result += 2
		nd += 1
		n //= 2
	d = 3
	while n > 1:
		while n % d == 0:
			result += d
			n //= d
			nd += 1
		d += 2
	return n + 1 if nd == 1 else result or n + 1
xs = [x for x in range(1, 20001) if x % spf(x) == 0]

def mult_primefactor_sum(a, b):
	i = bisect_left(xs, a)
	j = bisect_right(xs, b)
	return xs[i:j]


def mult_primefactor_sum(a, b):
	prime_factors = [factorize(n) for n in range(a, b + 1)]
	return [n for (n, pf) in enumerate(prime_factors, a) if len(pf) > 1 and n % sum(pf) == 0]

def memoize(func):
	cache = {}

	def wrapper(*args):
		if args not in cache:
			cache[args] = func(*args)
		return cache[args]
	return wrapper

@memoize
def factorize(n):
	if n < 2:
		return []
	factors = []
	for k in (2, 3):
		while n % k == 0:
			n //= k
			factors.append(k)
	k = 5
	step = 2
	while k * k <= n:
		if n % k:
			k += step
			step = 6 - step
		else:
			n //= k
			factors.append(k)
	if n > 1:
		factors.append(n)
	return factors


NUMS = [0, 0]

def mult_primefactor_sum(a, b):
	for n in range(len(NUMS), b + 1):
		(x, div, factors) = (n, 2, [])
		while x > 1:
			if x % div == 0:
				factors.append(div)
				x //= div
			else:
				div += 1 if div == 2 else 2
		if len(factors) == 1 or n % sum(factors) != 0:
			NUMS.append(0)
		else:
			NUMS.append(n)
	return [x for x in NUMS[a:b + 1] if x]


def primes(n):
	primfac = []
	d = 2
	while d * d <= n:
		while n % d == 0:
			primfac.append(d)
			n //= d
		d += 1
	if n > 1:
		primfac.append(n)
	return primfac

def mult_primefactor_sum(a, b):
	l = []
	for i in range(a, b + 1):
		factors = primes(i)
		if i > sum(factors) and (not i % sum(factors)):
			l.append(i)
	return l


def prime_factorizations(n):
	sieve = [0 for x in range(n)]
	for i in range(2, n):
		if not sieve[i]:
			sieve[i] = i
			for r in range(i, n, i):
				sieve[r] = sieve[r] or i
	return sieve

def factor_sum(sieve, n):
	results = 0
	while n > 1:
		p = sieve[n]
		results += p
		if p == n:
			break
		n //= p
	return results

def mult_primefactor_sum(a, b):
	sieve = prime_factorizations(b + 1)
	return [n for n in range(a, b + 1) if sieve[n] != n and n % factor_sum(sieve, n) == 0]


def prime_factors(n):
	if n % 2 == 0 and n > 0:
		return [2] + prime_factors(n // 2)
	for a in range(3, int(n ** 0.5) + 1, 2):
		if n % a == 0:
			return sorted(prime_factors(n // a) + prime_factors(a))
	return [n] if n > 1 else []

def mult_primefactor_sum(a, b):
	return [c for c in range(a, b + 1) if len(prime_factors(c)) > 1 and c % sum(prime_factors(c)) == 0]