def prime_gen():
    """A generator function that yields prime numbers using the `Sieve of
    Eratosthenes <http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes>`_
    algorithm.
       
    .. note::
    
        This function is based on the erat2a function which can be found
        `here <http://stackoverflow.com/a/3796442>`_. Variable names were
        changed and comments added for clarity.
    """
    yield 2
    comp_dict = {}
    for num in it_islice(it_count(3), 0, None, 2):
        p = comp_dict.pop(num, None)
        if p is not None:
            # num is a composite. Get the next composite that is not already
            # in the dictionary and that has p as prime factor. Add it to
            # the dictionary. The composite number is thus "sieved" out.
            # By taking a 2*p step, we avoid checking if test is even.
            test = num + 2 * p
            while test in comp_dict:
                test = test + 2 * p
            comp_dict[test] = p
        else:
            # num is a prime.
            # Add the first composite number that has 'num' as the
            # only prime factor to the composite numbers dictionary
            comp_dict[num * num] = num
            # return num
            yield num
Ejemplo n.º 2
0
def prime_gen():
    """A generator function that yields prime numbers using the `Sieve of
    Eratosthenes <http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes>`_
    algorithm.
       
    .. note::
    
        This function is based on the erat2a function which can be found
        `here <http://stackoverflow.com/a/3796442>`_. Variable names were
        changed and comments added for clarity.
    """
    yield 2
    comp_dict = {}
    for num in it_islice(it_count(3), 0, None, 2):
        p = comp_dict.pop(num, None)
        if p is not None:
            # num is a composite. Get the next composite that is not already
            # in the dictionary and that has p as prime factor. Add it to
            # the dictionary. The composite number is thus "sieved" out.
            # By taking a 2*p step, we avoid checking if test is even.
            test = num + 2 * p
            while test in comp_dict:
                test = test + 2 * p
            comp_dict[test] = p
        else:
            # num is a prime.
            # Add the first composite number that has 'num' as the
            # only prime factor to the composite numbers dictionary
            comp_dict[num * num] = num
            # return num
            yield num
def prime_wheel_fact_gen():
    """A generator function that yields prime numbers using the `wheel
    factorized <http://en.wikipedia.org/wiki/Wheel_factorization>`_ `Sieve of 
    Eratosthenes`_.
    
    .. note::
    
        This function is based on the erat3 function which can be found
        `here <http://stackoverflow.com/a/3796442>`_. Variable names were
        changed and comments added for clarity.
    """
    yield 2
    yield 3
    yield 5
    # The mask is used with itertools.compress method to generate prime
    # candidates after eliminating numbers using the wheel. The mask
    # contains a 1 when the corresponding number has 2,3 or 5 as a factor
    # only odd numbers are considered so the mask has only 15 values instead
    # of 30.
    wheel_mask = [
        0 if x % 3 == 0 or x % 5 == 0 else 1 for x in range(7, 37, 2)
    ]
    modulos = frozenset(
        [x % 30 for x in range(31, 61, 2) if x % 3 != 0 and x % 5 != 0])
    comp_dict = {}
    for num in it_compress(it_islice(it_count(7), 0, None, 2),
                           it_cycle(wheel_mask)):
        p = comp_dict.pop(num, None)
        if p is not None:
            # num is a composite. Get the next composite that is not already
            # in the dictionary, that meets the wheel criteria and that has p
            # as prime factor. Add it to the dictionary. The composite number
            # is thus "sieved" out.
            # By taking a 2*p step, we avoid checking if test is even.
            test = num + 2 * p
            while test in comp_dict or test % 30 not in modulos:
                test = test + 2 * p
            comp_dict[test] = p
            # delete 'num' from comp_dict to free memory.
        else:
            # num is a prime.
            # Add the first composite number that has 'num' as the
            # only prime factor to the composite numbers dictionary
            comp_dict[num * num] = num
            # return num
            yield num
Ejemplo n.º 4
0
def prime_wheel_fact_gen():
    """A generator function that yields prime numbers using the `wheel
    factorized <http://en.wikipedia.org/wiki/Wheel_factorization>`_ `Sieve of 
    Eratosthenes`_.
    
    .. note::
    
        This function is based on the erat3 function which can be found
        `here <http://stackoverflow.com/a/3796442>`_. Variable names were
        changed and comments added for clarity.
    """
    yield 2
    yield 3
    yield 5
    # The mask is used with itertools.compress method to generate prime
    # candidates after eliminating numbers using the wheel. The mask
    # contains a 1 when the corresponding number has 2,3 or 5 as a factor
    # only odd numbers are considered so the mask has only 15 values instead
    # of 30.
    wheel_mask = [0 if x % 3 == 0 or x % 5 == 0 else 1 for x in range(7, 37, 2)]
    modulos = frozenset([x % 30 for x in range(31, 61, 2) if x % 3 != 0 and x % 5 != 0])
    comp_dict = {}
    for num in it_compress(it_islice(it_count(7), 0, None, 2), it_cycle(wheel_mask)):
        p = comp_dict.pop(num, None)
        if p is not None:
            # num is a composite. Get the next composite that is not already
            # in the dictionary, that meets the wheel criteria and that has p
            # as prime factor. Add it to the dictionary. The composite number
            # is thus "sieved" out.
            # By taking a 2*p step, we avoid checking if test is even.
            test = num + 2 * p
            while test in comp_dict or test % 30 not in modulos:
                test = test + 2 * p
            comp_dict[test] = p
            # delete 'num' from comp_dict to free memory.
        else:
            # num is a prime.
            # Add the first composite number that has 'num' as the
            # only prime factor to the composite numbers dictionary
            comp_dict[num * num] = num
            # return num
            yield num