I want to enumerate all possible products of some integer factors, only up to some maximum value:
P((2, 3, 11), 10)
would return (2, 3, 4, 6, 8, 9)
.P((5, 7, 13), 30)
would return (5, 7, 13, 25)
.This seems like a tree traversal where the branches stop growing once reaching the maximum, but I don't know what the bound is on the number of branches. What algorithm or idiom is recommended for this problem? the closest thing I have seen so far is itertools.product()
, which seems to set a fixed number of terms per output set (e.g. 2).
For context, I am trying to inspect the numbers that are coprime to n. in this case n itself is the upper limit and the list of factors are those of n. I tried to generalize the question a bit above.
Many methods have been developed to count the numbers of bacteria in labs, but the most frequently used ones are standard plate count, turbidimetric method, and direct microscopic count.
Products intended for consumption in their raw form should contain less than 100 CFU/gram.
The most common procedure for the enumeration of bacteria is the viable plate count. In this method, serial dilutions of a sample containing viable microorganisms are plated onto a suitable growth medium.
USP 61 Microbial enumeration test is a quantitative test which determines the Total Aerobic Microbial Count (TAMC) and Total Yeast and Mold Count ( TYMC) present in the test product.
I like this method, which involves multiplying 1 by all the elements in the input list, then multiplying all the results by the elements in the input list, etc. until the limit is reached.
def signature_seq(signature, limit):
products = set((1,))
for factor in signature:
new_products = set()
for prod in products:
x = factor * prod
while x <= limit:
new_products.add(x)
x *= factor
products.update(new_products)
products.remove(1)
return products
This should do what you want:
>>> print(sorted(signature_seq((2, 3, 11), 10)))
[2, 3, 4, 6, 8, 9]
>>> print(sorted(signature_seq((5, 7, 13), 30)))
[5, 7, 13, 25]
By the way, if given a list of consecutive primes starting with 2, this is a smooth number generator.
Here's a solution using a generator (and itertools.count
):
from itertools import count
def products(numbers, limit):
numbers = set(numbers) # needs a set to pop from, not a tuple
while numbers:
n = numbers.pop()
for r in (n ** e for e in count(1)):
if r > limit:
break
yield r
for p in products(numbers, limit / r):
yield r * p
Since it is a generator, it returns an iterator - and the results aren't sorted, so for the specific output you want, you'd call it like this:
>>> sorted(products((2, 3, 11), 10))
[2, 3, 4, 6, 8, 9]
>>> sorted(products((5, 7, 13), 30))
[5, 7, 13, 25]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With