Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumeration of all factor products less than a maximum

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.

like image 287
Aaron Brick Avatar asked Jul 25 '13 00:07

Aaron Brick


People also ask

What are the enumeration methods?

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.

What is acceptable CFU?

Products intended for consumption in their raw form should contain less than 100 CFU/gram.

Which enumeration method is best?

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.

What is microbial enumeration test?

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.


2 Answers

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.

like image 108
bbayles Avatar answered Oct 19 '22 14:10

bbayles


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]
like image 38
Zero Piraeus Avatar answered Oct 19 '22 14:10

Zero Piraeus