Médaille
N°1 pour apprendre & réviser du collège au lycée.
Calcul du PGCD de deux nombres entiers (par l'algorithme d'Euclide) - Python
Découvrez, sur SchoolMouv, des milliers de contenus pédagogiques, du CP à la Terminale, rédigés par des enseignants de l’Éducation nationale.
Les élèves de troisième, de première ou de terminale bénéficient, en plus, de contenus spécifiques pour réviser efficacement leur brevet des collèges, leur bac de français ou leur baccalauréat édition 2023.
Fiche méthode

Introduction :

Nous avons appris en cours à déterminer le PGCD\text{PGCD} de deux nombres entiers aa et bb en nous servant de l’algorithme d’Euclide.
Dans cette fiche, nous allons tout simplement voir comment programmer cet algorithme en Python. Bien sûr, votre calculatrice dispose déjà d’une fonction qui calcule directement le PGCD\text{PGCD} de deux entiers, mais cela nous permettra de bien comprendre l’algorithme d’Euclide et de programmer un algorithme simple en Python.

Algorithme d’Euclide

Rappelons avant tout en quoi consiste l’algorithme d’Euclide.

Commençons par nous souvenir de cette propriété.

bannière propriete

Propriété

Pour tout entier relatif aa, nous avons :

PGCD(a ;0)=a\text{PGCD}(a\ ;\, 0)=\vert a\vert

Nous avons aussi appris et démontré la propriété suivante.

bannière propriete

Propriété

Soit aa et bb deux entiers naturels non nuls, et rr le reste de la division euclidienne de aa par bb.

  • Nous avons alors : PGCD(a ;b)=PGCD(b ;r)\text{PGCD}(a\ ;\, b)=\text{PGCD}(b\ ;\, r).

Voici en quoi consiste l’algorithme d’Euclide :

  • nous effectuons d’abord la division euclidienne de aa par bb, obtenons le reste r1r_1 ;
  • ensuite, pour chaque division suivante et tant que le reste obtenu est différent de 00 :
  • le diviseur de la division précédente devient dividende,
  • le reste de la division précédente devient diviseur.
  • Le PGCD\text{PGCD} de aa et bb sera égal au dernier reste non nul.

Illustrons par un petit tableau cet algorithme :

Division Dividende Diviseur Reste
1\scriptsize 1 a=bq1+r1\footnotesize{a=bq1+r1} a\footnotesize a b\footnotesize b r1\footnotesize{r1} PGCD(a ;b)=PGCD(b ;r1)\scriptsize{\text{PGCD}(a\ ;\,b)=\text{PGCD}(b\ ;\,r1)}
2\scriptsize 2 b=r1q2+r2\footnotesize{b=r1q2+r2} b\footnotesize b r1\footnotesize{r1} r2\footnotesize{r2} PGCD(b ;r1)=PGCD(r1 ;r2)\scriptsize{\text{PGCD}(b\ ;\,r1)=\text{PGCD}(r1\ ;\,r2)}
3\scriptsize 3 r1=r2q3+r3\footnotesize{r1=r2q3+r3} r1\footnotesize{r1} r2\footnotesize{r2} r3\footnotesize{r3} PGCD(r1 ;r2)=PGCD(r2 ;r3)\scriptsize{\text{PGCD}(r1\ ;\,r2)=\text{PGCD}(r2\ ;\,r3)}
n1\scriptsize{n-1} rn3=rn2qn1+rn1\footnotesize{r{n-3}=r{n-2}q{n-1}+r{n-1}} rn3\footnotesize{r{n-3}} rn2\footnotesize{r{n-2}} rn1\footnotesize{r{n-1}} PGCD(rn3 ;rn2)=PGCD(rn2 ;rn1)\scriptsize{\text{PGCD}(r{n-3}\ ;\,r{n-2})=\text{PGCD}(r{n-2}\ ;\,r{n-1})}
n\scriptsize n rn2=rn1qn+0\footnotesize{r{n-2}=r{n-1}q{n}+0} rn2\footnotesize{r{n-2}} rn1\footnotesize{r{n-1}} rn=0\footnotesize{r{n}=0} PGCD(rn2 ;rn1)=PGCD(rn1 ;0)=rn1\begin{aligned} \scriptsize \text{PGCD}(r{n-2}\ ;\,r{n-1})&\scriptsize =\text{PGCD}(r{n-1}\ ;\,0) \ &\scriptsize=r{n-1} \end{aligned}
  • PGCD(a ;b)=rn1\text{PGCD}(a\ ;\, b)=r_{n-1}.
bannière exemple

Exemple

Prenons un exemple et déterminons le PGCD\text{PGCD} de 20702\,070 et 368368 :

Division Dividende Diviseur Reste
1\scriptsize 1 2070=368×5+230\footnotesize{2\,070=368\times 5+230} 2070\footnotesize{2\,070} 368\footnotesize{368} 230\footnotesize{230} PGCD(2070 ;368)=PGCD(368 ;230)\scriptsize{\text{PGCD}(2\,070\ ;\,368)=\text{PGCD}(368\ ;\,230)}
2\scriptsize 2 368=230×1+138\footnotesize{368=230\times 1 + 138} 368\footnotesize{368} 230\footnotesize{230} 138\footnotesize{138} PGCD(368 ;230)=PGCD(230 ;138)\scriptsize{\text{PGCD}(368\ ;\,230)=\text{PGCD}(230\ ;\,138)}
3\scriptsize 3 230=138×1+92\footnotesize{230=138\times 1 + 92} 230\footnotesize{230} 138\footnotesize{138} 92\footnotesize{92} PGCD(230 ;138)=PGCD(138 ;92)\scriptsize{\text{PGCD}(230\ ;\,138)=\text{PGCD}(138\ ;\,92)}
4\scriptsize 4 138=92×1+46\footnotesize{138=92\times 1+46} 138\footnotesize{138} 92\footnotesize{92} 46\footnotesize{46} PGCD(138 ;92)=PGCD(92 ;46)\scriptsize{\text{PGCD}(138\ ;\,92)=\text{PGCD}(92\ ;\,46)}
5\scriptsize 5 92=46×2+0\footnotesize{92=46\times 2+0} 92\footnotesize{92} 46\footnotesize{46} 0\footnotesize{0} PGCD(92 ;46)=PGCD(46 ;0)=46\begin{aligned} \scriptsize \text{PGCD}(92\ ;\,46)&\scriptsize =\text{PGCD}(46\ ;\,0) \ &\scriptsize =46 \end{aligned}
  • PGCD(2070 ;368)=46\text{PGCD} (2\,070\ ;\, 368) = 46.

Algorithme Python

Une fois la logique de l’algorithme Python bien compris, le programme Python correspondant devient assez simple à réaliser.

  • Nous créons la fonction pgcd\purple{\text{pgcd}}, qui prendra pour paramètres les deux entiers strictement positifs a\purple{\text{a}} et b\purple{\text{b}} :

def pgcd(a, b):\text{def pgcd(a, b):}
  • Nous allons effectuer les divisions successives tant que le reste obtenu est non nul.
  • C’est donc notre condition pour notre boucle while\purple{\text{while}} :

\text{while a \% b != 0:}
bannière rappel

Rappel

Opérateurs Python pour la division euclidienne :

  • a % b\purple{\text{a \% b}} renvoie le reste de la division euclidienne de a\purple{\text{a}} par b\purple{\text{b}} ;
  • a // b\purple{\text{a // b}} renvoie le quotient (entier) de la division euclidienne de a\purple{\text{a}} par b\purple{\text{b}}.
  • Comme nous l’avons dit plus haut, le diviseur de la division précédente devient le dividende, et le reste de la division précédente devient le diviseur.
  • Nous assignons donc à a\purple{\text{a}} la valeur de b\purple{\text{b}} et à b\purple{\text{b}} le reste de la division euclidienne de a\purple{\text{a}} par b\purple{\text{b}} :

a, b = b, a % b\text{a, b = b, a \% b}
bannière attention

Attention

Il ne faut surtout pas écrire :

a = bb = a % b\begin{aligned} &\text{a = b} \ &\text{b = a \% b} \end{aligned}

En effet, avec ce code, quand la nouvelle valeur de b\purple{\text{b}} est assignée, a\purple{\text{a}} a déjà sa nouvelle valeur, soit celle de b\purple{\text{b}}, et nous obtiendrions systématiquement b=0\purple{\text{b}}=0.
Pour résoudre ce problème, nous pouvons créer une variable intermédiaire :

c = aa = bb = c % b\begin{aligned} &\text{c = a} \ &\text{a = b} \ &\text{b = c \% b} \end{aligned}

Toutefois, la solution que nous avons choisie plus haut est la plus directe et permet de ne pas créer inutilement une nouvelle variable.

  • Lorsqu’on sortira de la boucle, b\purple{\text{b}} contiendra le dernier reste non nul.
  • Nous l’affichons donc :

print(b)\text{print(b)}
bannière à retenir

À retenir

L’algorithme est terminé :

\begin{aligned} \textcolor{#A9A9A9}{\text{1}}&\quad\text{def pgcd(a, b):} \ \textcolor{#A9A9A9}{\text{2}}&\quad\qquad\text{while a \% b != 0:} \ \textcolor{#A9A9A9}{\text{3}}&\quad\qquad\qquad\text{a, b = b, a \% b} \ \textcolor{#A9A9A9}{\text{4}}&\quad\qquad\text{print(b)} \end{aligned}
  • Vous pouvez vérifier que vous trouvez le même résultat que dans la première partie pour le PGCD\text{PGCD} de 20702\,070 et 368368.

Terminons par quelques remarques.

Que se passe-t-il si a<b\purple{\text{a}} < \purple{\text{b}} ?
Le reste de la division euclidienne de a\purple{\text{a}} par b\purple{\text{b}} sera égal à a\purple{\text{a}}. Au premier tour de boucle, les valeurs de a\purple{\text{a}} et b\purple{\text{b}} seront inversées et nous aurons alors a>b\purple{\text{a}} > \purple{\text{b}}.

  • Ainsi, il est inutile de différencier les cas a>b\purple{\text{a}} > \purple{\text{b}} et a<b\purple{\text{a}} < \purple{\text{b}}, puisqu’on se ramène toujours et rapidement au premier.

Nous avons en outre considéré que a\purple{\text{a}} et b\purple{\text{b}} étaient des entiers naturels non nuls.
Que se passe-t-il si a\purple{\text{a}} est nul ?
Eh bien, 00 étant un multiple de tout nombre entier, le reste de la division euclidienne de 00 par tout nombre entier bb sera égal à 00.
Nous n’entrons ainsi pas dans la boucle et l’algorithme renverra la valeur intiale de b\purple{\text{b}}.

  • Ce qui est juste, puisque nous savons que, pour tout entier naturel bb, PGCD(0 ;b)=b\text{PGCD}(0\ ;\, b)=b.

Maintenant, que se passe-t-il si c’est b\purple{\text{b}} qui est nul ?
Ici, effectivement, notre programme ne va pas aimer cette tentative de division par 00

  • À vous de compléter l’algorithme pour qu’il prenne en compte de ce cas particulier !

Enfin, nous avons travaillé avec a\purple{\text{a}} et b\purple{\text{b}} entiers naturels.
Nous pourrions aussi compléter l’algorithme pour qu’il fonctionne aussi pour des entiers relatifs, en renvoyant bien une valeur positive.

  • Encore à vous de jouer ! Il suffit de se rappeler que, pour tout aa et bb entiers relatifs :

PGCD(a ;b)=PGCD(a ;b)\text{PGCD}(a\ ;\, b)=\text{PGCD}(\vert a\vert\ ;\, \vert b\vert)

bannière astuce

Astuce

Pour prendre la valeur absolue d’un nombre x\purple{\text{x}} en Python, on fait appel à la fonction abs\purple{\text{abs}} :

abs(x)\purple{\text{abs(x)}}