n° 105
Exercice d'entraînement · niveau 3 (difficile) · NSI (première), chapitre 3 — Langages et programmation · Écrire et spécifier ses propres fonctions
Énoncé
Écrire est_premier(n). Justifier que la boucle peut s'arrêter dès que — et non seulement à . Comparer le nombre de divisions des deux versions, puis vérifier qu'elles donnent le même résultat sur à .
Corrigé
def est_premier(n):
"""Vrai si n est un nombre premier.
Precondition : n est un entier >= 0.
Postcondition : le resultat vaut True si et seulement si n >= 2 et n n'a
pas d'autre diviseur que 1 et lui-meme.
"""
assert n >= 0
if n < 2:
return False
d = 2
while d * d <= n:
if n % d == 0:
return False
d = d + 1
return True
Pourquoi suffit. Si est composé, il s'écrit avec . Alors , donc : tout nombre composé possède un diviseur inférieur ou égal à sa racine carrée. Si aucun diviseur n'a été trouvé jusque-là, il n'y en a pas du tout.
Le gain. La version naïve essaie diviseurs, la version arrêtée à la racine en essaie environ . Pour , c'est divisions contre : un facteur mille. Le coût passe de proportionnel à à proportionnel à — et l'écart grandit avec .
La vérification différentielle. On écrit la version naïve, dont on est sûr, et on compare :
def est_premier_naif(n):
if n < 2:
return False
for d in range(2, n):
if n % d == 0:
return False
return True
for n in range(0, 3000):
assert est_premier(n) == est_premier_naif(n)
Les cas concordent. Contrôles : les premiers inférieurs à obtenus sont bien les attendus, de à . Et n'est pas premier, tandis que et le sont.
Les cas limites qui comptent : et ne sont pas premiers — par définition, pas par accident. l'est, et c'est le seul premier pair : la boucle ne s'exécute pas () et la fonction rend True. est le plus petit cas où la boucle sert vraiment.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.