Given a list of prime factors, ```primesL```, and an integer, ```limit```, try to generate in order, all the numbers less than the value of ```limit```, that have **all and only** the prime factors of ```primesL```

## Example
```python
primesL = [2, 5, 7]
limit = 500
List of Numbers Under 500          Prime Factorization
___________________________________________________________
           70                         [2, 5, 7]
          140                         [2, 2, 5, 7]
          280                         [2, 2, 2, 5, 7]
          350                         [2, 5, 5, 7]
          490                         [2, 5, 7, 7]
```

There are ```5``` of these numbers under ```500``` and the largest one is ```490```.

## Task

For this kata you have to create the function ```count_find_num()```, that accepts two arguments: ```primesL``` and ```limit```, and returns the amount of numbers that fulfill the requirements, and the largest number under `limit`.

The example given above will be:
```python
primesL = [2, 5, 7]
limit = 500
count_find_num(primesL, val) == [5, 490]
```

If no numbers can be generated under `limit` then return an empty list:
```python
primesL = [2, 3, 47]
limit = 200
find_nums(primesL, limit) == []
```

The result should consider the limit as inclusive:
```python
primesL = [2, 3, 47]
limit = 282
find_nums(primesL, limit) == [1, 282]
```

Features of the random tests:
```
number of tests = 200
2 <= length_primesL <= 6 // length of the given prime factors array
5000 <= limit <= 1e17
2 <= prime <= 499  // for every prime in primesL
```

Enjoy!

Source: codewars | Difficulty: EASY
Tags: Dynamic programming

Data structures

Mathematics

Starter code: def count_find_num(primesL, limit):
	

Solutions:
def count_find_num(primes, limit):
	base = eval('*'.join(map(str, primes)))
	if base > limit:
		return []
	results = [base]
	for p in primes:
		for num in results:
			num *= p
			while num not in results and num <= limit:
				results += [num]
				num *= p
	return [len(results), max(results)]


from functools import reduce

def count_find_num(primesL, limit):

	def rec(n, primes):
		if not primes:
			return
		(x, (y, *next_primes)) = (n, primes)
		while x <= limit:
			if x != n:
				yield x
			yield from rec(x, next_primes)
			x *= y
	start = reduce(int.__mul__, primesL)
	if start > limit:
		return []
	result = [start] + list(rec(start, primesL))
	return [len(result), max(result)]


from functools import reduce
from collections import deque

def count_find_num(primesL, limit):
	q = deque()
	q.append(reduce(lambda x, y: x * y, primesL))
	(Max, Count) = (0, 0)
	while len(q) != 0:
		if q[0] <= limit:
			Count += 1
			Max = max(Max, q[0])
			for i in primesL:
				if i * q[0] <= limit and i * q[0] not in q:
					q.append(i * q[0])
		q.popleft()
	return [Count, Max] if Count != 0 and Max != 0 else []


from functools import reduce

def count_find_num(primesL, limit):
	base_num = reduce(lambda a, b: a * b, primesL, 1)
	if base_num > limit:
		return []
	nums = [base_num]
	for i in primesL:
		for n in nums:
			num = n * i
			while num <= limit and num not in nums:
				nums.append(num)
				num *= i
	return [len(nums), max(nums)]


def count_find_num(primesL, n):
	base = 1
	for p in primesL:
		base *= p
	arr = permPrime(base, primesL, n)
	if len(arr) == 0:
		return []
	return [len(arr), max(arr)]

def permPrime(base, primesL, n):
	if base > n:
		return []
	arr = [base]
	for p in primesL:
		arr += permPrime(base * p, primesL, n)
	arr = list(set(arr))
	return arr


from functools import reduce
from itertools import chain

def count_find_num(primesL, limit):
	s = [reduce(lambda a, b: a * b, primesL)]
	if s[0] > limit:
		return []
	r = set(s)
	while len(s) > 0:
		s = set(chain.from_iterable(([p * n for p in primesL if p * n <= limit] for n in s)))
		r |= s
	return [len(r), max(r)]


from bisect import insort
from functools import reduce

def count_find_num(primesL, n):
	product = reduce(lambda a, b: a * b, primesL)
	if product > n:
		return []
	p = [product]
	last = None
	count = 0
	while p:
		first = p.pop(0)
		if first == last:
			continue
		count += 1
		for x in primesL:
			m = x * first
			if m <= n:
				insort(p, m)
		last = first
	return [count, last] if count else []


def multiplyList(myList):
	result = 1
	for x in myList:
		result = result * x
	return result

def count_find_num(primesL, limit):
	base = multiplyList(primesL)
	primesL.sort()
	list1 = [base]
	i = base
	for i in primesL:
		for j in list1:
			d = j
			while d < limit:
				d = d * i
				if d <= limit:
					list1.append(d)
	if len(list1) == 1 and list1[0] > limit:
		return []
	else:
		list2 = list(set(list1))
		return [len(list2), max(list2)]


from functools import reduce
from collections import deque

def count_find_num(primesL, limit):
	initial_product = reduce(lambda prod, x: prod * x, primesL, 1)
	if initial_product > limit:
		return []
	found_numbers = set()
	queue = deque([initial_product])
	while len(queue) > 0:
		item = queue.popleft()
		found_numbers.add(item)
		for p in primesL:
			prod = p * item
			if prod <= limit:
				queue.append(prod)
	return [len(found_numbers), max(found_numbers)]


import math
import itertools

def count_find_num(primesL, limit):
	exps = [int(math.log(limit, p)) + 1 for p in primesL]
	exps = exps + [2, 2, 2, 2, 2, 2]
	exps = exps[0:5]
	primesL = (primesL + [1, 1, 1, 1])[0:5]
	res = set()
	for a in range(1, exps[0]):
		for b in range(1, exps[1]):
			for c in range(1, exps[2]):
				for d in range(1, exps[3]):
					for e in range(1, exps[4]):
						x = primesL[0] ** a * primesL[1] ** b * primesL[2] ** c * primesL[3] ** d * primesL[4] ** e
						if x <= limit:
							res.add(x)
	return [len(res), max(res)] if res else []