# -*- coding: utf-8 -*-

r"""
Exemples simples de générateurs
"""

def naturels():
    r"""
    Retourne un générateur des nombres naturels.

    Note: Ce générateur est infini.
    """
    n = 0
    while True:
        yield n
        n += 1

def est_premier(n):
    r"""
    Retourne vrai si et seulement si n est un naturel premier.
    """
    for i in range(2, int(sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True

def premiers():
    r"""
    Retourne un générateur des nombres premiers.

    Note: Ce générateur est infini
    """
    p = 2
    while True:
        if est_premier(p):
            yield p
        p += 1

def premiers_fini(m):
    r"""
    Retourne un générateur des nombres premiers plus petit ou égal à n.

    ENTRÉE:

    ``m`` (naturel): une borne supérieure des nombres générés
    """
    p = 2
    while p <= m:
        if est_premier(p):
            yield p
        p += 1

def mots(alphabet, n):
    r"""
    Retourne un générateur de tous les mots de longueur n sur l'alphabet donné.

    ENTRÉES:

    - ``alphabet`` (ensemble de lettres): l'alphabet
    - ``n`` (naturel): la longueur
    """
    if n == 0:
        yield ''
    else:
        for u in mots(alphabet, n - 1):
            for a in alphabet:
                yield u + a
