Lyc´ee Thiers - MPSI-3

publicité
Lycée Thiers
TP PYTHON - 02
PARTIE A - Quelques rappels de cours
1. définir des fonctions
Nous avons déjà rencontré des fonctions prédéfinies sur les entiers, les flottants et les itérables. Par
exemple : sqrt, print, int, input.
On peut aussi définir ses propres fonctions. Voici deux exemples :
def perimetreC(r):
print(2*pi*r)
def plusProcheEntier(x):
if x % 1 < 0.5:
return x//1
else:
return x//1+1
[Qu. 1]
1) Recopier la définition des deux fonctions dans un fichier de l’éditeur et exécuter ce fichier. Que
se passe-t-il ?
2) Saisir et exécuter dans le shell : perimetreC(1); plusProcheEntier(-1.3) . Comment corriger
cette erreur ? Comment expliquer que Python n’ait pas détecté ce problème plus tôt ? Corriger
cette erreur et exécuter perimetreC(1); plusProcheEntier(-1.3) à nouveau.
3) Saisir dans une cellule de l’éditeur perimetreC(1); plusProcheEntier(-1.3) et exécuter cette
cellule. Comment expliquer que les deux fonctions ne se comportent pas de façon similaire ?
[Qu. 2] Ecrire une fonction plusProcheP(x,p) qui renvoie l’entier multiple de p le plus proche de x.
[Qu. 3] On souhaite écrire une fonction qui permute les objets contenus dans 2 variables.
1) Essayer le script suivant :
a = 1; b = 2
def permute(x, y):
z=x; x=y; y=z
permute(a, b)
print(a)
print(b)
2) Que constatez-vous ? Rajouter l’instruction print(id(x)) dans la définition de la fonction et
print(id(a)) juste après l’exécution de la fonction permute puis exécuter à nouveau le script.
Les nouvelles valeurs affichées sont-elles cohérentes avec vos précédentes constatations ?
I On a ici observé que les paramètres d’une fonction, ici a et b, sont transmis par valeur et non
par référence. On peut d’ailleurs exécuter l’instruction permute(2,3) sans que cela génère une
erreur.
3) Proposer une solution sous la forme d’une fonction retournant un couple.
TP PYTHON - 02
2
2. manipulations avancées sur les listes
[Qu. 4] L’expression [k**2 for k in range(1,11)] calcule la liste des carrés des entiers de 1 à 10.
En s’inspirant de cet exemple, écrire :
1) une expression calculant la liste des 10 premiers nombres impairs.
2) une fonction affichant la liste des n premiers nombres impairs.
3) une fonction renvoyant la liste des n premiers nombres impairs.
[Qu. 5] L’expression L.remove(x) modifie la liste L en supprimant la 1ère occurrence de x dans L et
en préservant l’ordre des termes.
1) Essayer ceci :
>>>
>>>
>>>
>>>
>>>
L = [1, 2, 3, 1]
L.remove(1)
print(L)
L.remove(1)
print(L)
2) Pour produire la liste des entiers compris entre 50 et 100 et qui ne sont pas multiples de 7, on peut
utiliser une construction qui prolonge celle vue en Qu-4. Essayer ceci :
>>> [k for k in range(50, 101) if k % 7 != 0]
Bien entendu, on pouvait aussi construire la liste de tous les entiers compris entre 50 et 100,
puis retirer de celle-ci les termes multiples de 7. En utilisant successivement ces deux méthodes,
écrire une fonction non_multiples(a, b, d) qui renvoie la liste croissante des entiers compris
entre a et b et qui ne sont pas multiples de d.
Remarque. Les expressions de la forme
[expr for count in iterable]
ou bien
[expr for count in iterable if condition]
sont appelées des “listes en compréhension” (comprehension lists, en anglais). Elles constituent un
moyen puissant pour générer une liste lorsqu’une formule pour son terme général est connue.
L’itérable en question peut très bien être une liste ; essayer par exemple ceci :
>>> L = [k ** 2 for k in range(1, 11)]
>>> [q - 1 for q in L]
# ici, l’itérable est range(1, 11)
# là, l’itérable est la liste L
PARTIE B - Quelques questions de divisibilité
Rappels
Etant donnés a ∈ N? et b ∈ N? , on dit que a est un diviseur de b lorsque ∃k ∈ N; b = ka.
On note alors a | b. On exprime la même relation en disant que b est un multiple de a.
Si a | b et a , b, on dit que a est un diviseur strict de b (ou que b est un multiple strict de a).
Un entier n > 2 est dit premier lorsque ses seuls diviseurs sont 1 et n.
L’ensemble des nombres premiers est noté P.
On appelle nombre parfait tout entier naturel qui est la somme de ses diviseurs stricts. Le plus petit
nombre parfait est donc 6 = 1 + 2 + 3. Le suivant est 28 = 1 + 2 + 4 + 7 + 14.
TP PYTHON - 02
3
Cette notion, qui remonte pourtant à l’antiquité, recelle à ce jour une importante part de mystère. Par
exemple, la question de savoir s’il existe une infinité de nombres parfaits n’est pas résolue. On ne sait
pas non plus s’il existe des nombres parfaits impairs !
3. Nombres parfaits
[Qu. 6] Ecrire une fonction diviseurs_stricts(n) qui renvoie la liste croissante des
stricts
diviseurs
n
de son argument n. Pour cela, on essaiera un à un chaque entier compris entre 1 et
.
2
>>> diviseurs_stricts(30)
[1, 2, 3, 5, 6, 10, 15]
[Qu. 7] Ecrire une fonction parfait(n) qui renvoie True ou False selon que n est parfait ou non.
>>> parfait(28)
True
[Qu. 8] En déduire une fonction liste_parfaits(nmax) qui affiche les nombres parfaits inférieurs
ou égaux à nmax (à raison d’un nombre par ligne). Quels sont les nombres parfaits inférieurs ou égaux
à 104 ? Ce calcul ne devrait pas prendre plus qu’une poignée de secondes ...
Remarque. On verra plus bas une méthode nettement plus efficace pour énumérer les diviseurs d’un
entier, ce qui améliorera du coup la performance de l’énumération des nombres parfaits.
4. Nombres premiers, parfaits, amicaux
[Qu. 9] Le crible d’Eratosthène 1 est un procédé visant à établir la liste croissante des nombres premiers
inférieurs ou égaux à n, pour un certain entier n > 2. En voici une première version :
On commence par dresser la liste des entiers de 2 à n. On repète alors les opérations suivantes :
on coche le plus petit terme de la liste (qui ne soit pas déjà coché) puis on supprime de la liste ses
multiples stricts. Cette itération se termine quand tous les entiers de la liste sont cochés.
Voici une illustration de ce qui précède, pour n = 25 :
2
2
2
2
2
2
2
2
2
2
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
3
5
7
9
11
13
15
17
19
21
23
25
3
5
7
11
13
17
19
23
25
3
5
7
11
13
17
19
23
3
5
7
11
13
17
19
23
3
5
7
11
13
17
19
23
3
5
7
11
13
17
19
23
3
5
7
11
13
17
19
23
3
5
7
11
13
17
19
23
3
5
7
11
13
17
19
23
Ecrire une fonction crible(n) qui renvoie la liste des nombres pemiers inférieurs ou égaux à n, en
utilisant cette méthode.
[Qu. 10] Montrer que si n ne possède aucun diviseur d tel que 2 6 d 6
j√ k
n , alors n ∈ P.
[Qu. 11] En déduire que l’on peut interrompre l’algorithme du crible beaucoup plus tôt ! Modifier la
fonction crible(n) en conséquence.
1. Eratosthène de Cyrène, III-ème siècle avant JC. Astronome, géographe et mathématicien. Il fut nommé à la tête de la
bibliothèque d’Alexandrie. Outre le crible qui porte son nom, on lui doit la première mesure connue du méridien terrsetre.
TP PYTHON - 02
4
[Qu. 12] Soit n > 2 et soit p = min {d ∈ N − {0, 1} ; d | n} . Justifier que p ∈ P puis écrire une fonction
ppfp(n) qui renvoie le plus petit facteur premier d’un entier n > 2.
[Qu. 13] En invoquant de façon répétée la fonction ppfp, on obtient tous les facteurs premiers d’un
entier n > 2. Détailler ce processus – à la main, puis en contrôlant avec l’ordinateur – pour n = 5888069.
[Qu. 14] Ecrire une fonction pre_dfp(n) qui renvoie la liste des facteurs premiers de n, chacun d’eux
étant répété le bon nombre de fois. Par exemple, étant donné que 1350 = 2 × 33 × 52 , on aura :
>>> pre_dfp(1350)
[2, 3, 3, 3, 5, 5]
[Qu. 15] On souhaite obtenir une forme plus compacte pour la décomposition en facteurs premiers
d’un entier ... quelque chose du genre :
>>> dfp(1350)
[[2, 1], [3, 3], [5, 2]]
1) Ecrire une fonction reduc_liste(L) qui, à partir d’une liste d’entiers L = [r1 , · · · , rn ] renvoie,
sous la forme d’une liste de listes de longueur 2, les différents termes de L et le nombre de fois
que chacun d’eux apparaît consécutivement. Par exemple :
>>> reduc_liste([1,2,2,2,1,1,3,3,3,1,1])
[[1, 1], [2, 3], [1, 2], [3, 3], [1, 2]]
2) Ecrire, en combinant ce qui précède, la fonction dfp.
[Qu. 16] Ecrire une fonction gen_prod(L, p, n) qui, partir d’une liste L d’entiers, construit la liste
déduite de L en multipliant chacun de ses termes par les pk pour 0 6 k 6 n.
[Qu. 17] En déduire, en combinant les fonctions dfp et gen_prod, une fonction diviseurs(n) qui
renvoie (plus efficacement qu’à la question Q-3) la liste croissante des diviseurs d’un entier n.
[Qu. 18] Calculer de nouveau les nombres parfaits inférieurs ou égaux à 104 et constater (expérimentalement) le gain de performance.
[Qu. 19] Dresser (par ordinateur) une table indiquant, pour 2 6 n 6 31, si 2n − 1 est premier ou
non. Observer et conjecturer un énoncé reliant les deux assertions n ∈ P et 2n − 1 ∈ P. Sauriez-vous
prouver cette conjecture ?
[Qu. 20] On suppose que p ∈ P et 2p − 1 ∈ P. On note Ep = 2p−1 (2p − 1) .
1) Quels sont les diviseurs de Ep ? Que vaut leur somme ? Que peut-on en déduire concernant Ep ?
2) En déduire un cinquième nombre parfait (normalement, quatre nombres parfaits ont été détectés
aux questions Q-3 et Q-15).
[Qu. 21] On dit que deux entiers naturels forment un couple de nombres amicaux lorsque chacun
d’eux est la somme des diviseurs stricts de l’autre. Vérifier qu’il n’existe, parmi les couples (a, b) tels
que 1 6 a < b 6 300, qu’un seul couple de nombres amicaux et le déterminer.
Téléchargement