Devoir Maison sur feuille : nombres premiers. Pour le 9 janvier.

publicité
Devoir Maison sur feuille : nombres premiers.
Pour le 9 janvier.
Informatique Pour Tous - 2016/2017
Si vous ne l’avez pas déjà fait, et si vous en avez la possibilité, il est fortement conseillé de
télécharger Pyzo, en allant sur http://test.pyzo.org/downloads.html. Si par exemple vous
avez Windows, vous pouvez télécharger win64.zip, dezipper et ensuite exécuter pyzo.exe dans le
dossier dézippé. Vous pourrez ainsi tester vos réponses dans Pyzo. Le DM doit cependant être
rendu écrit, sur papier.
On rappelle qu’un entier naturel est premier lorsqu’il a exactement deux diviseurs : 1 et luimême. Si a et b sont deux entiers, on rappelle que a // b et a % b donnent le quotient et le
reste de la division euclidienne de a par b, respectivement.
1. (a) Écrire une fonction divise qui prend deux entiers naturels a, b en arguments avec a
non nul et renvoie True si a divise b, False sinon.
(b) Écrire une fonction diviseurs qui prend un entier naturel non nul n en argument et
renvoie la liste des diviseurs de n.
(c) Écrire une fonction premier qui prend un nombre en argument et renvoie True si ce
nombre est premier, False sinon.
(d) Écrire une fonction tous_premiers qui prend un entier naturel n en argument et
renvoie la liste de tous les nombres premiers inférieurs ou égaux à n.
(e) Quelle est la complexité dans le pire des cas de tous_premiers ? On admettra que
les opérations a // b et a % b de python ont chacune une complexité O(ln(a)).
2. Le crible d’Ératosthène est un algorithme beaucoup plus efficace pour obtenir la liste des
nombres premiers inférieurs à un entier n.
On part d’une liste L de taille n + 1 dont tous les éléments sont des booléens de valeur
√
True. On modifie la valeur de L[0] et L[1] à False. Puis pour chaque i entre 2 et b nc,
si L[i] contient True, alors pour chaque k multiple de i et strictement supérieur à i, on
modifie L[k] en False. A la fin, L[i] égal True si i est premier, False sinon. On pourra
écrire int(x) pour calculer la partie entière d’un flottant x.
(a) Écrire une fonction eratosthene qui prend un nombre n en argument et renvoie la
liste L décrite ci-dessus.
(b) En utilisant la fonction eratosthene, écrire une fonction tous_premiers2 qui prend
un entier naturel n en argument et renvoie la liste de tous les nombres premiers
inférieurs ou égaux à n.
(c) Quelle est la complexité dans le pire des cas de tous_premiers2 ? Comparer avec
tous_premiers. Si vous avez accès à Pyzo, vous pouvez comparer experimentalement
le temps d’exécution des deux fonctions : par exemple, écrire
1
%timeit(tous_premiers(1000)) dans le shell donne le temps d’exécution moyen de
tous_premiers(1000).
3. Nous nous intéressons maintenant au calcul du PGCD en Python. On rappelle l’algorithme d’Euclide permettant de calculer le PGCD de deux entiers a et b, où a > b :
Tant que b > 0 :
r = reste de la division de a par b
a=b
b=r
Renvoyer a
(a) Écrire une fonction pgcd implémentant l’algorithme d’Euclide en python.
(b) Montrer que l’algorithme d’Euclide a pour complexité dans le pire des cas O((ln(a))2 ).
Pour cela on pourra d’abord montrer (ou admettre) que, si ri est la suite des restes
(où r0 est le premier reste), ri+2 < ri /2.
4. Nous allons utiliser une autre méthode de calcul de PGCD, basée sur la décomposition
en facteurs premiers.
(a) Écrire une fonction decomposition ayant un argument n et qui renvoie la liste L des
diviseurs premiers de n avec multiplicités. On pourra stocker dans chaque élément de L
une liste composée de deux entiers naturels : le diviseur et sa multiplicité. Par exemple
decomposition(50) devra renvoyer la liste [[2, 1], [5, 2]], puisque 50 = 21 ×52 .
(b) En déduire une autre fonction pgcd2 renvoyant le PGCD de deux entiers naturels
en arguments, en utilisant decomposition. Quelle est sa complexité ? Comparer avec
l’algorithme d’Euclide.
(c) Écrire aussi une fonction ppcm renvoyant le PPCM de deux entiers naturels en arguments.
2
Téléchargement