Vous êtes sur la page 1sur 44

Quelques aspects

d’algorithmique de base
Et implémentation en Turbo Pascal

Roland Yonaba
Etudiant en Master 1 – Option Eau – 2010-2011
29/11/2010
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Quelques aspects d’algorithmique de base

Et implémentation en Turbo-Pascal

Par Roland O Yonaba

Etudiant au 2IE en Master 1 – Option Eau (Année 2010-2011)

E-mail : roland.yonaba@gmail.com

Yonaba_sroland@yahoo.com

1
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Sommaire

I. Calculs et opérations numériques ................................................................................................... 4


1. Somme d’entiers entre deux bornes définies ............................................................................. 6
2. Somme d’entiers de 1 à n ............................................................................................................ 8
3. Calcul d’une factorielle ................................................................................................................ 9
4. Calcul de ............................................................................................................................... 12
5. Les nombres parfaits ................................................................................................................. 14
6. PGCD de deux entiers A et B ..................................................................................................... 16
7. PPCM de deux entiers A et B ..................................................................................................... 20
8. Combinaisons de p-uplets dans un ensemble n-uplets............................................................. 21
9. Test de primalité d’un entier positif N ...................................................................................... 22
10. Conjecture de Goldbach ........................................................................................................ 24
11. Définir une fonction polynomiale de degré N ....................................................................... 25
12. Les nombres d’Armstrong ..................................................................................................... 27
II. Itérations, Convergence, Conversions, Approximations, simulations de problèmes ................... 28
1. Approximation de la « divine proportion ». .............................................................................. 30
2. Simulation de lancer d’une pièce de monnaie .......................................................................... 32
3. Approximation de Pi par la méthode statistique ...................................................................... 34
4. Calcul Intégral d’une fonction polynomiale .............................................................................. 37
5. Table de Gauss........................................................................................................................... 40
En conclusion… ...................................................................................................................................... 43

2
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

L’objet de la programmation est le plus souvent la résolution certaines situations complexes,


pour peu qu’elles soient modélisables, par l’automatisation d’un long processus de calcul. A cet effet,
le programmeur se doit de savoir effectuer des tâches minimalistes, telles les calculs de convergence,
la génération aléatoire, le tri de données, etc.

Considérez donc le cours suivant comme un guide d’initiation à quelques problèmes


fondamentaux de la programmation. Il n’est certainement pas exhaustif, et n’en a pas la moindre
prétention, mais très certainement il vous sera plus qu’utile. Les diverses notions dont nous
traiterons par la suite seront abordées de la façon le plus simple possible, et l’élaboration des codes
sources en Turbo-Pascal suivra la même logique.

Il est possible que des erreurs se soient glissées dans le présent document, bien que j’aie fait
tout mon possible pour que cela ne soit pas. « Errare Humanum est », dit-on; il vous appartient donc
de me soumettre lesdites erreurs, afin que je puisse les corriger promptement.

Vous vous interrogerez certainement sur la façon d’aborder ce document…A priori, aucune.
Les différents problèmes dont je traite sont catégorisés, suivant leur degré de complexité. Il va de soi
que vous ne devrez par parcourir ce document de bout en bout, comme vous liriez un roman, mais
plutôt en cherchant ce qui vous intéresse via le sommaire des sujets traités. Notez bien que chaque
nouveau problème sera abordé de la manière suivante :

 Le problème posé
 Sa résolution progressive en langage courant puis en langage Pascal.

La plus grave des erreurs serait de considérer ce document comme un cours d’initiation au
Turbo-Pascal. Il n’en est pas un. En effet, je suppose ici que vous connaissez déjà (et plutôt bien) la
manipulation du langage Pascal. La base est de savoir au moins concevoir un programme, définir et
employer une fonction, une procédure, utiliser les structures conditionnelles, itératives, répétitives,
savoir compiler et exécuter un programme.

L’essentiel ayant été dit, il ne reste plus à vous souhaiter que ce document vous sera
pleinement utile. Faites-en bon usage !

R.Y.

3
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

I. Calculs et opérations numériques

4
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Dans cette première partie, afin de nous familiariser avec les concepts élémentaires de la
programmation, nous allons tenter de résoudre des problèmes simples. Il s’agira pour la plupart des
cas de formules de calcul déjà à mettre sus code. Pour d’autres cas, vous apprendrez (en douceur)
quelques algorithmes de calcul très simples qui pourront vous être utiles plus tard.

Pour cette partie, vous pourrez bien entendu lire simplement l’énoncé, et tenter de le résoudre,
avant de lire la solution proposé. Je vous le recommande vivement, car la plupart des 12 problèmes
qui vont suivre sont à votre portée.

Sur ce, bon code !

5
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

1. Somme d’entiers entre deux bornes définies

Ecrire un programme qui calcule et affiche la somme des nombres entiers de 1 à 10.

Résolution

Il s’agit probablement de l’un des problèmes les plus triviaux, mais qui à l’intérêt de former
utilement à la manipulation des structures itératives.

L’objectif est de concevoir un programme qui calcule la quantité :

L’on pourrait probablement penser à un programme de ce genre :

program calcul_somme;
uses wincrt;

var somme:integer;

begin
somme := 1+2+3+4+5+6+7+8+9+10;
writeln(somme);
end.

Ce programme donnerait certes la bonne réponse. Mais, que lui reprocher ? D’être à la limite
un programme…« stupide ».

Imaginez un instant qu’il nous avait été demandé de calculer la somme des entiers de 1 à 100
plutôt, et que nous voudrions utiliser la même méthode…On devrait donc s’échiner à modifier la
ligne somme := 1+2+3+4+5+67+8+9+10; en somme = 1+2+3+4… et continuer la saisie jusqu’à 100…Ce
qui est impensable en programmation.

Notez une chose, la programmation relève souvent de la paresse… Toujours chercher donc le
chemin le plus court.

6
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Il suffit de constater que nous voulons calculer ∑ .Un structure itérative ferait très bien
l’affaire :

program calcul_somme;
uses wincrt;

var somme,i:integer;

begin
somme:=0;

for i:=1 to 10 do somme:=somme+i;

writeln(somme); Figure 1. Résultat de l'exécution


end.

7
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

2. Somme d’entiers de 1 à n

Ecrire un programme qui reçoit de son utilisateur un nombre entier n et qui calcule et affiche
la somme des entiers de 1 à n.

Résolution

Ce problème devient encore plus simple une fois que l’on a traité l’Exercice I de cette même partie.

Nous voulons calculer la quantité : ∑ . Sauf qu’ici, léger détail qui a son importance, la borne n
n’est pas définie dans notre programme, mais doit être entrée par l’utilisateur.

Nous aurons donc besoin de :

 Récupérer la borne n
 Calculer et afficher la somme des entiers de 1 à n avec une structure itérative (une boucle
for).

Ce qui nous conduit à la solution suivante :

program calcul_somme;
uses wincrt;

var somme,i,n:integer;

begin
somme:=0;
writeln('Entrez la borne n');
read(n);
for i:=1 to n do somme:=somme+i;
Figure 2. Exemple avec n=12
writeln('somme = ',somme);
end.

8
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

3. Calcul d’une factorielle

Concevoir un programme qui calcule la factorielle d’un nombre entier n défini par l’utilisateur.

Résolution

Nous voici sans nul doute en présence d’un problème plus complexe que ce que nous venons
de voir jusqu’alors.
Nous savons tous que la factorielle d’un nombre se définit comme étant le produit des
nombres inférieurs ou égal à ce nombre :

( ) ( ) ∏

Nous allons donc utiliser une structure itérative pour calculer le produit des nombres de 1 à
n, avec n étant reçu d’un utilisateur de notre programme :

program calcul_factorielle;
uses wincrt;

var factorielle,n,i:integer;

begin
factorielle:=1;
writeln('Entrez la borne n');
read(n);
for i:=1 to n do factorielle:=factorielle*i;

writeln('factorielle = ',factorielle);
end.

Et c’est tout !

Essayez d’entrer les nombres suivants et de comparer les résultats fournis par le programme avec les
résultats exact :
 0 ! = 1 (convention mathématique, rappelez-vous-en !)
 1!=1
 2 ! = 2x1 = 2
 3 ! = 3x2x1 = 6
 4 ! = 4x2x1 = 24
 5 ! = 5x4x3x2x1 = 120
 6 !=6x5x4x3x2x1 = 720
 7 !=7x6x5x4x3x2X1 = 5040

Pour aller plus loin …

9
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Jusqu’ici, le programme semblait fiable. Essayez cependant le calcul de factorielle avec 8.


 8 ! = 8x7x6x5x4x3x2x1 = 40320.
Tandis que programme vous affichera (tenez-vous bien) : -25216 !

Où se trouve le problème ?

Et bien, il réside dans la définition de nos types de variables. Nous avons déclaré au départ la
variable factorielle (censée contenir le résultat final) en type integer. Oui, il est vrai que factorielle est
toujours un nombre entier, mais le problème est le suivant :

Le type integer, (étant stocké sur un espace de 2 octets, donc sur 16 bits, dont 1 de signe, mais ça
vous vous en fichez complètement…) ne peut contenir QUE DES NOMBRES ENTIERS COMPRIS ENTRE

Donc, puisque 8 ! = 40320, 8! ne peut pas rentrer dans un integer, et le programme affiche
donc n’importe quoi…

Remédier au problème est simple…Il suffit de déclarer factorielle en un type différent. Par
exemple longint. C’est le plus grand conteneur d’entiers existant en Pascal. Il peut contenir des
nombres compris entre
.
Mais par exemple, vous serez limité à 12 !

Voici donc une amélioration possible de votre programme :

program calcul_factorielle;
uses wincrt;

var factorielle:longint;
n,i:integer;

begin
factorielle:=1;
writeln('Entrez la borne n (inférieure ou égale à 12 svp !)');
read(n);
for i:=1 to n do factorielle:=factorielle*i; Figure 3. Exemple de calcul avec n=12

writeln('factorielle = ',factorielle);
end.

Pour aller encore plus loin…

10
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Voilà, nous avons donc conçu un programme qui sait calculer la factorielle d’un nombre. Du
moins, pour un nombre positif entier inférieur à 12. Il se peut que dans certains cas, nous ayons
besoin de calculer la factorielle d’un nombre pour l’employer dans un autre calcul plus complexe. Il
serait alors judicieux de transformer le précédent programme en une fonction qui retourne la
factorielle d’un nombre n pris en paramètre. L’exemple concret :

program calcul_factorielle;
uses wincrt;

{Fonction calculant la factorielle de n}


function factorielle(n:integer):longint;
var i:integer;
produit:longint;
begin
produit:=1;
for i:=1 to n do produit:=produit*i;
factorielle:=produit;
end;

{Début du programme principal}


var n:integer;
begin
writeln('Entrez la borne n (inférieure ou égale à 12 svp !)');
read(n);
writeln('factorielle = ',factorielle(n));
end.

11
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

4. Calcul de

Ecrire une fonction en Pascal qui retourne un nombre x élevé à une puissance entière y. Les
valeurs x et y seront définies par l’utilisateur du programme.

Résolution

Voilà une fois de plus le genre d’exercice qui se résout très simplement une fois que nous
avons défini ce que nous cherchons. Ici, c’est calculer : .

Clarifions auparavant les choses. Ici, l’énoncé nous simplifie la vie en nous imposant y étant
un nombre entier ! Cependant, aucune précision sur la nature de x, qui peut être un réel !

Nous pouvons donc conclure très rapidement : x élevé à la puissance y, c’est le produit de x
par lui-même y fois ! Utilisons donc la boucle for, qui est parfaite dans ce cas.

program calcul_puissance;
uses wincrt;

var puissance,x:real;
y,i:integer;

begin
puissance:=1;
writeln('Entrez le nombre x:');
readln(x);
writeln('Entrez la puissance y:'); Figure 4. Calcul de 4^3
readln(y);
for i:=1 to y do puissance:=puissance*x;
writeln('puissance = ',puissance);
end.

12
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Voilà donc le programme général. L’énoncé demande toutefois d’en faire une fonction qui
retournerait la factorielle. Qu’à cela tienne, une légère modification le permet.

program calcul_puissance;
uses wincrt;

{Fonction renvoyant x^y}


function puissance(x:real;y:integer):real;
var p:real;
i:integer;
begin
p:=1;
for i:=1 to y do p:=p*x;
puissance:=p;
end;

{Reste du programme principal}


var x:real;
y:integer;
begin
writeln('Entrez le nombre x:'); readln(x);
writeln('Entrez la puissance y:'); readln(y);
writeln('puissance = ',puissance(x,y));
end.

13
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

5. Les nombres parfaits

« Un nombre entier est dit parfait s’il est égal à la somme de ses diviseurs stricts ». Ecrire un
programme qui cherche et affiche les 4 premiers nombres parfaits.

Résolution

Cet exercice est assez simple puisqu’il s’agit essentiellement d’identifier les diviseurs stricts
d’un nombre entier positifs. L’opérateur modulo va nous être d’un grand recours.

Le modulo d’une division de A par B est le reste de la division entière de A par B. Si vous le
saviez déjà, prenez cela comme un rappel…

Donc 5 modulo 3 = 2, car 5/3 = 1 et reste 2. C’est tout simple.

Remarquons que si A modulo B = 0, alors A est multiple de B ou B est diviseur de A, prenez ça


comme vous le voulez. Vérifions-le illico presto.

6/3 = 2 reste 0..Donc 3 est diviseur de 6… on peut aussi dire 6 est multiple de 3.

Cela va peut-être vous étonner, mais l’exercice est pratiquement résolu ! La démarche que
nous allons employer est la suivante :

Etape 1 : Fixer la variable comptant les nombres parfaits trouvés à 0.


Etape 2: Commencer par un nombre (1 de préférence).
Etape 3 : Fixer la somme de ses diviseurs à 0.
Etape 4 : Calculer le modulo de ce nombre par tous les entiers strictement inférieurs à ce nombre. Si
pour une division, le modulo est nul, on rajoute le diviseur à la somme des diviseurs.
Etape 5 : Une fois la somme des diviseurs trouvés, on compare le nombre à la somme des diviseurs.
S’ils sont égaux, on affiche le nombre, et on augmente de 1 la variable comptant de nombres parfaits
trouvés.
Etape 6 : On passe au nombre suivant et on répète l’étape 3, jusqu’à ce que la variable comptant les
nombres trouvés soit égale à 4.

14
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Voici le programme correspondant :

program nombres_parfaits;
uses wincrt;

var nombre_trouves,somme_diviseurs,nombre_actuel,i:integer;
begin
nombre_trouves:=0;
nombre_actuel:=1;
repeat
somme_diviseurs:=0; Figure 5 : Nombres parfaits
for i:=1 to (nombre_actuel-1) do
if ((nombre_actuel mod i)=0) then somme_diviseurs:=somme_diviseurs+i;
if (nombre_actuel = somme_diviseurs) then begin
writeln(nombre_actuel);
nombre_trouves:=nombre_trouves+1;
end;
nombre_actuel:=nombre_actuel+1;
until (nombre_trouves=4);
end.

15
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

6. PGCD de deux entiers A et B

Construire une fonction qui calcule le PGCD de deux nombres entiers a et b qui sont définis
par l’utilisateur.

Résolution

Pour la résolution d’un tel programme, il ne serait pas superflu de commencer par quelques
rappels mathématiques.

Le PGCD se définit comme étant le Plus Grand Commun Diviseur de deux entiers. Pour un
couple de nombres entier-décimal, ou un couple décimal-décimal, le PGCD n’existe pas.
Bien entendu, si l’un des nombres est égal à zéro, leur PGCD est alors nul…

Nous avons appris dans les classes antérieures à calculer le PGCD à partir de la
décomposition en nombres premiers. Par exemple pour le calcul du PGCD(20,10) ;
( )
Effectivement le plus grand diviseur commun à 10 et à 20 est bien 10…

Autre exemple, pour le PGCD(38,12) :


( )

Nous n’allons cependant pas appliquer ici ce procédé de calcul qui est assez long, mais utiliser
des algorithmes de calcul rapide du PGCD. Je vous offre ici principalement deux de ces méthodes :
 La méthode d’Euclide
 La méthode Egyptienne

Méthode d’Euclide

Elle est d’une simplicité extrême. Voici son principe :

Soient deux entiers A et B tels que A soit supérieur à B :


Soit un nombre R
REPETER LES OPERATIONS SUIVANTES
Calculer R = modulo de A/B (c’est-à-dire le reste de la division entière de A par B)
A prend la valeur de B
B prend la valeur de R
JUSQU'A CE QUE R SOIT EGAL A ZERO
PGCD = A

16
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

L’élève aime bien avoir l’illustration des propos théoriques. Soit, voici un exemple
d’application. Nous cherchons le PGCD (12,15) .

 Nous prenons donc A=15 et B = 12 (car A doit être supérieur à B)


A/B = 15/12 = 1 et reste 3. Donc R=3.
A = 12 (l’ancienne valeur de B) et B = 3 (la valeur de R)
 Comme R ne vaut pas 0, reprenons.
A/B = 12/3 = 4 et reste 0. Donc R = 0.
A=3 (la précédente valeur de B) et B = 0 (la précédente valeur de R).
 R vaut 0, On s’arrête.
Le PGCD est A, soit 3.

Nous allons mettre en application ce procédé, mais avec toutefois quelques optimisations :
Nous remarquons tout de suite un léger handicap.

Cette façon de calculer le PGCD ne marche qu’avec un nombre A supérieur à un nombre B. Nous
devrons nous charger nous-mêmes de permuter A et B si ce n’est pas le cas.
De plus nous pouvons faire certains constats sur le calcul du PGCD.
 Si A ou B est nul, leur PGCD est automatiquement nul.
 Si A = B alors leur PGCD (A,B ) = A = B
 Si A, étant plus grand que B, est multiple de B, alors PGCD(A,B ) = B

Ces constatations sont importantes dans la mesure où elles peuvent nous permettre
d’accélérer le calcul du PGCD. Voici donc comment nous composerons notre fonction

Fonction PGCD(entiers A et B) : retourne un entier


Soit R un entier
DEBUT.FONCTION
S’assurer que A > B auquel cas, les permuter en s’appuyant sur R.
SI (A=0) ou (B=0) alors STOP. PGCD =0
SINON
SI (A=B) alors STOP.PGCD =A
SINON
SI (A est multiple de B) ALORS STOP.PGCD =B
SINON
REPETER
R = RESTE de A/B
A=B
B=R
JUSQU'A CE QUE (R=0)
PGCD = A
FIN.FONCTION

Et voici un programme dans lequel cette fonction est définie et appelée par le programme
principal :

17
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

function pgcd(a,b:integer):integer;
var r:integer;
begin
if (a<b) then begin r:=a; a:=b; b:=r; end;
if (a=0) or (b=0) then pgcd:=0
else
if (a=b) then pgcd:=a
else
if ((a mod b)=0) then pgcd:=b
else
begin
repeat
r:=a mod b;
a:=b;
b:=r;
Figure 6. Calcul PGCD (0,4)
until (r=0);
pgcd:=a;
end;
end;

Méthode Egyptienne

Cette seconde méthode est tout aussi aisée à appliquer. Voici son principe :

Soient A et B deux entiers


REPETER LES OPERATIONS SUIVANTES
SI (A>B) ALORS A = A-B
SINON B = B-A
JUSQU'à CE QUE A SOIT EGAL à B
PGCD = A ou B

Nous allons construire donc notre fonction sur le principe suivant :

Fonction EPGCD (entiers A, B) : retourne un entier ;


DEBUT.FONCTION
SI (A=0) ou (B=0) alors STOP.PGCD = 0
SINON
TANT QUE (A Différent de B)
SI (A>B) alors A= A-B
SINON B= B-A
FIN TANT.QUE
PGCD = A
FIN.FONCTION

Et voici le code associé :

function Epgcd(a,b:integer):integer;
begin
18
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

if (a=0) or (b=0) then Epgcd:=0


else
while (a<>b) do
if (a>b) then a:=a-b else b:=b-a;
Epgcd:=a;
end;

19
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

7. PPCM de deux entiers A et B

Concevoir une fonction qui calcule le PPCM de deux nombres entiers a et b. Ecrire un
programme qui emploie cette fonction. Les nombres a et b seront définis par un utilisateur.

Résolution

Ce problème est une suite logique du précédent. Ici encore, pour obtenir le PPCM (Plus Petit
Commun Multiple) de deux nombres, il faut passer par leur décomposition en facteurs premiers.
Cependant, nous allons encore préférer un autre principe mathématique, qui nous sauvera la mise :
Soient A et B deux entiers positifs :

 Si A=0 ou B=0 alors PPCM (A, B) = 0


 Si A et B simultanément différents de 0, alors ( )
( )

Difficile de faire plus simple...Le problème est ramené donc à un simple calcul de PGCD,
aspect qui traité à l’Exercice VI.
Nous allons donc réemployer la fonction de calcul de PGCD par la méthode Egyptienne (c’est
la plus courte à écrire, pardi !) pour construire celle du calcul du PPCM. Ensuite l’associer à un
programme principal qui demandera deux entiers a et b à l’utilisateur et affichera leur PPCM en
appelant la fonction de calcul du PPCM, que nous aurons auparavant définie (vous me suivez
toujours… ?).

program calcul_ppcm;
uses wincrt;

{Fonction renvoyant le pgcd de deux entiers a et b}


function Epgcd(a,b:integer):integer;
begin
if (a=0) or (b=0) then Epgcd:=0
else
while (a<>b) do
if (a>b) then a:=a-b else b:=b-a;
Epgcd:=a;
end;

{Fonction renvoyant le ppcm de deux entiers a et b}


function ppcm(a,b:integer):integer;
begin
if (a=0) or (b=0) then ppcm:=0
else
ppcm:=trunc((a*b)/Epgcd(a,b));
end;

var a,b:integer;
begin
writeln('Entrez le nombre a:'); readln(a);
writeln('Entrez le nombre b:'); readln(b); Figure 7. Calcul PPCM(12,22)
writeln('ppcm = ',ppcm(a,b));
end.

20
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

8. Combinaisons de p-uplets dans un ensemble n-uplets.

Ecrire une fonction qui calcule les combinaisons de p-éléments dans un ensemble fini de n-éléments.

Résolution

C’est un exercice simple une fois que le problème général est dégagé. En effet, les
mathématiques nous enseignent que :

( )

Imaginons que nous sachions calculer la factorielle d’un nombre. La fonction que l’on nous
demande ici devient simple à concevoir :

Fonction combinaison (entiers n, p) : renvoie un entier ;


DEBUT.FONCTION
Combinaison = factorielle(n)/[factorielle(p)*factorielle(n-p)]
FIN.FONCTION

Le calcul de la factorielle d’un nombre est déjà traité à l’Exercice III. Nous allons simplement
réutiliser le code de la fonction factorielle qui y est défini pour arriver à nos fins.

program calcul_combinaison;
uses wincrt;

{Fonction renvoyant la factorielle de n}


function factorielle(n:integer):longint;
var i:integer;
produit:longint;
begin
produit:=1;
for i:=1 to n do produit:=produit*i;
factorielle:=produit; Figure 8. Calcul des Comb. de 4 dans 10
end;

{Fonction renvoyant les combinaisons de p dans n}


function combinaison(n,p:integer):integer;
begin
combinaison:=trunc(factorielle(n)/(factorielle(p)*factorielle(n-p)));
end;

var n,p:integer;
begin
writeln('Entrez le nombre n:'); readln(n);
writeln('Entrez le nombre p:'); readln(p);
writeln('combinaison(p,n) = ',combinaison(n,p));
end.

21
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

9. Test de primalité d’un entier positif N

Ecrire une fonction qui prend en paramètre un entier n et qui renvoie :

 Vrai si le nombre en question est un nombre premier


 Faux le cas échéant.

La fonction sera nommée Est_Premier(). L’utiliser dans un programme.

Résolution

Ne pas paniquer devant un tel énoncé. C’est en effet beaucoup plus simple qu’il n’y paraît.

 La question à se poser, c’est : « Qu’est-ce qu’un nombre premier ? ».


 La réponse : « Un nombre est premier s’il est seulement divisible par 1 et par lui-même ».

Cependant il existe une convention mathématique selon laquelle 1 n’est pas un nombre premier.

Pour arriver à nos fins, nous allons nous baser sur quatre postulats :

 1 n’est pas premier. C’est une convention.


 Un nombre entier est toujours divisible par 1. C’est une évidence. Aucun besoin donc de
chercher à le vérifier.
 Un nombre entier est toujours divisible par lui-même. C’est encore une évidence.
 Si le reste du rapport d’un entier A par un entier B inférieur est nul (A modulo B = 0) alors A
est multiple de B (c’est une fois de plus une évidence).

Pour savoir si un nombre N est premier, il suffit donc de le diviser successivement par tous
les nombres entiers strictement supérieurs à 1 et qui lui sont strictement inférieurs. Si le reste d’une
de ces divisions est nul, alors le nombre N possède un sous-multiple, est n’est donc pas premier.
Sinon, bingo ! N est premier.

22
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

program test_de_primalite;
uses wincrt;

function Est_premier(n:integer):boolean;
var i:integer;
divisible:boolean;
begin
if (n=1) then Est_premier:=false
else begin
divisible:=false;
for i:=2 to (n-1) do
if ((n mod i)=0) then divisible:=true;
if (divisible) then Est_premier:=false Figure 9. Test de primalité de 7
else Est_premier:=true;
end;
end;

var n:integer;
begin
writeln('Entrez un nombre n'); read(n);
writeln('Entrez le nombre n:');
writeln(n,' est-il premier ? ',Est_premier(n));
end.

23
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

10. Conjecture de Goldbach

Un théorème qui ne possède pas de démonstration s’appelle une conjecture. L’objectif est de
construire un programme qui illustre la conjecture de Goldbach.
Christian Goldbach fût un mathématicien russe qui a émis l’hypothèse suivante en 1742 :
« Tout nombre pair est la somme de deux nombres premiers ».

Construire un programme qui illustre cette conjecture pour un nombre entier défini par un
utilisateur.

Résolution

Voilà un programme qui est enrichissant, du point de vue culture générale. Nous découvrons
la conjecture de Goldbach…
Comment le résoudre ? En le décomposant en sous-tâches.
Nous partons donc avec un nombre pair N.
Dans un premier temps, nous allons rechercher tous les couples de valeurs (A, B) tels que N=A+B. Par
exemple, pour N = 8, nous retiendrons les couples : (1,7) , (2,6) , (3,5) , (4,4).

Ensuite, pour chaque couple (A, B) généré, nous vérifierons si A et B sont simultanément
premiers. Une fonction permettant de savoir si un nombre est premier a été déjà définie à l’Exercice
VIII. Nous allons ici réutiliser cette fonction ici.

program conjecture_goldbach;
uses wincrt;

{Fonction effectuant le test de primalité d’un entier n}


function Est_premier(n:integer):boolean;
var i:integer;
divisible:boolean;
begin
if (n=1) then Est_premier:=false
else begin
divisible:=false;
for i:=2 to (n-1) do
if ((n mod i)=0) then divisible:=true;
if (divisible) then Est_premier:=false else Est_premier:=true;
end;
end;

{Programme principal}
var n,a,b,i:integer; Figure 7. Conjecture de GoldBach sur le nombre 100
begin
writeln('Entrez un nombre n'); read(n);
if ((n mod 2)<>0) then writeln(n,' n''est par pair!')
else
for i:=1 to (n div 2) do begin
a:=i; b:=n-i;
if Est_premier(a) and Est_premier(b) then writeln(n,' = ',a,' + ',b);
end;
end.

24
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

11. Définir une fonction polynomiale de degré N


Concevoir un programme un programme permettant de calculer la valeur en un point réel x0
de n’importe qu’elle fonction polynomiale f(x). Le degré de la fonction, ses coefficients ainsi que le
paramètre x0 seront définis par l’utilisateur. Notez que le paramètre x0 peut être un réel. Le résultat
f(x0) sera arrondi à 2 décimales à l’affichage.

Résolution
Commençons par définir ce à quoi nous voulons aboutir. Ici, il s’agit de calculer f(x0) avec f
étant une fonction polynomiale, de degré n.
Qu’est- ce -qu’une fonction polynomiale ?
Simplement une fonction de R vers R, qui à tout réel x associe la quantité :
( )
Nous remarquons tout de suite une chose : La fonction est entièrement définie une fois que
nous connaissons les coefficients .
De plus, chaque monôme suit la même construction. Un coefficient , multiplié par le réel x
élevé à la puissance i….
D’où la forme condensée :

( ) ∑

Pour arriver à un programme fonctionnel, il faudrait déjà que nous sachions programmer le
calcul d’un réel x élevé à la puissance i. Problème déjà traité à l’Exercice IV.
Fort de cet atout, nous allons concevoir notre programme de cette manière.

Soient : les réels A, x0, F


Et les entiers N et I
Début.Programme
Initialiser F à 0.
Récupérer dans x0 la valeur en laquelle il faut calculer f.
Récupérer dans N le dégré de la fonction polynomiale
Pour i allant du dégré N à 0
Récupérer dans A le coefficient .
Calculer , rajouter à F
Fin.Pour
Afficher F
Fin.Programme

Toutefois, attention! Ceci n’est qu’un algorithme général, qui vous présente le squelette final
du programme, et son fonctionnement. En pratique, il est impossible en Pascal de calculer de façon
brute x0 à la puissance i…comme je l’explique plus haut. Cette ligne devra donc être remplacée par
l’appel à une fonction qui fera ce travail. Nous n’aurons qu’à recopier le code de la fonction
puissance() qui a fait l’objet de l’Exercice IV.

Dernier détail, l’énoncé nous demande l’affichage de la solution avec 2 décimales. Pour cela il
suffit de rajouter deux paramètres sur le réel f lorsqu’on l’affiche :

( )

Dans notre cas, nous ferons : ( )

25
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Le programme final :

program calcul_f(x0);
uses wincrt;

{Fonction renvoyant x à la puissance y}


function puissance(x:real;y:integer):real;
var p:real;
i:integer;
begin
p:=1;
for i:=1 to y do p:=p*x;
puissance:=p;
end;

{programme principal}
var a,n,i:integer;
f,x0:real;
begin
writeln('Entrez le point x0'); readln(x0);
writeln('Entrez le degré'); readln(n); Figure 8. Calcul de f(-3) avec f(x) = x^2
f:=0;
for i:=n downto 0 do
begin
writeln('Entrez le coefficient de x^',i,':'); readln(a);
f:=f+(a*puissance(x0,i));
end;
writeln('f(',x0:0:2,') = ',f:0:2);
end.

26
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

12. Les nombres d’Armstrong

« Un nombre d’Armstrong est un nombre entier qui est égal à la somme des cubes des chiffres
dont il se compose ». Sachant qu’il existe 4 de ces nombres compris entre 100 et 999, écrire un
programme qui cherche et affiche ces 4 nombres.

Résolution

Nous cherchons donc 4 nombres compris entre 100 et 999. Ce sont donc obligatoirement des
nombres à 3 chiffres. Un chiffre des centaines, un chiffre des dizaines et un dernier pour les unités. Si
le nombre est abc alors :

Le nombre abc sera dit nombre d’Armstrong si en notant ce nombre abc, on a :

Pour identifier de tels nombres, il suffit de faire varier simultanément trois chiffres a, b et c :

 Le premier chiffre a, utilisé pour identifier le chiffre des centaines, variera entre 1 et 9.
 Le 2ème chiffre b, utilisé pour identifier le chiffre des dizaines, variera entre 0 et 9.
 Le 3ème chiffre c, utilisé pour identifier le chiffre des unités, variera entre 0 et 9.

Pour chaque nombre abc formé, on fera le test suivant :

Si alors on affichera le nombre abc.

program nombres_amrstrong;
uses wincrt;

var a,b,c,somme_cubes,nombre:integer;

begin
for a:=1 to 9 do
for b:=0 to 9 do
for c:=0 to 9 do
begin
somme_cubes:=(a*a*a)+(b*b*b)+(c*c*c);
nombre:=(100*a)+(10*b)+c;
Figure 9. Les 4 nombres d'Armstrong
if (somme_cubes=nombre) then writeln(nombre);
end;
end.

27
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

II. Itérations, Convergence, Conversions, Approximations,


simulations de problèmes

28
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Dans cette partie, les problèmes abordés seront quelques peu différents de ceux traités jusqu’alors. Il
ne s’agira plus de calculs simples, mais de véritables « sujets de recherche ». La démarche adoptée
est la suivante :

 La présentation du problème posé


 La méthode de résolution détaillée (à l’aide schémas illustratifs)
 L’implémentation de l’algorithme dégagé

Par conséquent, à titre de conseil, il vous faudra avoir bien maitrisé les quelques concepts de
la première partie, et être à l’aise dans la manipulation du langage Turbo Pascal avant d’aborder la
suite.

Bon code !

29
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

1. Approximation de la « divine proportion ».

L’objectif principal de cet exercice est d’approcher une grandeur célèbre, appelée « nombre
d’or » ou encore la « divine proportion ».

Soit un segment AB, et un point C sur ce segment.

Ce segment doit être tel que le rapport de la plus grande partie de AB sur la plus petite partie
de AB est toujours égal au segment AB sur sa plus grande partie. Autrement dit, ici :

En posant AC=x et CB = 1, on a :


La seule solution positive de cette équation est notée et vaut exactement . Le
nombre est appelé « nombre d’or ».

Il existe deux manières d’approcher le nombre d’or par critère de convergence :

 1ère méthode :
( )
( )

√ √ √ √ √
 2ème méthode : √

Construire deux procédures (une procédure pour chaque méthode) calculant le nombre d’or. Ces
procédures prendront un unique paramètre epsilon, correspondant à la précision de calcul, et
devront :

Afficher le nombre d’or à epsilon près une fois trouvé. Renvoyer aussi le nombres d’itérations qu’il a
fallu effectuer pour trouver le nombre d’or à epsilon près

Indication : Pour effectuer un calcul à epsilon près, il suffit de répéter le calcul jusqu’à ce que
deux résultats consécutifs soient proches de moins de epsilon.

30
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Résolution

Nous allons d’abord chercher à construire la première procédure de calcul du nombre d’Or.
Elle prend en paramètre un réel, qui est la précision epsilon. Elle renvoie le rang auquel le nombre
d’or à epsilon près est trouvé.

Le principe est simple. Nous partons avec deux variables phi1 et phi2.

Etape 1 : On fixe phi1 = 1. On a effectué 0 itérations jusqu’alors.

Les instructions suivantes seront répétées jusqu’à ce que | | :

 Etape 2 : On fixe phi2 = phi1


 Etape 3 : On calcule phi1 = 1+ (1/phi1), on augmente de 1 le nombre d’itérations
 Etape 4 : On compare le nouveau phi1 à phi2…S’ils sont distants de moins de epsilon, la
précision est atteinte, sinon, on reprend à l’étape 2.

procedure nombredor(epsilon:real);
var rang:integer;
phi1,phi2:real;
begin
phi1:=1;
rang:=0;
repeat
phi2:=phi1;
phi1:=1+(1/phi1); {Ligne explicitant le processus iteratif}
rang:=rang+1;
until (abs(phi1-phi2)<epsilon);
writeln('nombre d''or: ',phi1);
writeln('nombre d''itérations nécessaires : ',rang);
end;

La deuxième procédure sera construite de façon similaire. Je vous épargne les longs discours:

procedure nombredor2(epsilon:real);
var rang:integer;
phi1,phi2:real;
begin
phi1:=1;
rang:=0;
repeat
phi2:=phi1;
phi1:=sqrt(1+phi1); {Ligne explicitant le processus itératif}
rang:=rang+1;
until (abs(phi1-phi2)<epsilon);
writeln('nombre d''or: ',phi1);
writeln('nombre d''itérations nécessaires : ',rang);
end;

31
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

2. Simulation de lancer d’une pièce de monnaie

On désire effectuer une simulation de lancer d’une pièce de monnaie. L’objectif est de
construire un programme simulant 100 jets de pièce de monnaie à l’issue duquel il affiche :

 Le nombre d’occurrences de « Pile ».


 Le nombre d’occurrences de « Face ».

Pour simuler le jet d’une pièce de monnaie, le programme devra choisir un nombre au hasard
entre 1 et 100. Si le nombre est strictement inférieur à 50, cela correspond à l’issue « Pile ».S’il est
strictement supérieur à 50, cela correspond à l’issue « Face ». Mais si le nombre pris au hasard est
égal à 50, en générer un nouveau.

Résolution

C’est un exercice facile à résoudre dans son principe général. Il nous aidera à comprendre le
fonctionnement de la génération aléatoire, qui est un aspect de la programmation à connaitre
nécessairement.

Souvent, dans certains programmes, l’on a besoin de générer des valeurs « au hasard »,
avant de les traiter par des instructions diverses. Cela est possible grâce à la fonction random(), qui
est commune à quasiment tous les langages de programmation.

En exécutant ainsi une ligne telle que : ( ), la variable y contient un entier


compris entre 0 et 10…mais on ne sait pas lequel. A moins d’afficher le contenu de cette variable.
Pour plus de détails sur l’emploi de la fonction random(), vous pouvez vous référer à la
documentation de Borland Pascal.

Pour revenir au problème qui nous est soumis, une tentative de réponse serait un
programme répétant 100 fois les étapes suivantes dans ce genre :

 Générer un nombre aléatoire entre 0 et 100.


 Si ce nombre est inférieur à 50, alors on le compte pour Pile. S’il est supérieur à 50, on le
compte pour « Face ». S’il est égal à 50, on en génère un nouveau qui soit différent de 50.

La solution est disponible plus bas. Cependant, vous noterez que j’emploie en début de
programme une procédure, Randomize ; Son utilité ?

Pour comprendre l’utilité de cette procédure, il faut savoir que pour une machine à calcul,
générer des nombres aléatoires relève d’un parcours du combattant. Car il faut que cela soit fait de
manière à ce qu’il n’y n’apparaisse pas à l’observation de la série de valeurs générés une loi
d’évolution apparente…La plupart des systèmes de génération de valeurs aléatoires possèdent une
série prédéfinie de valeurs, dans laquelle ils puisent des valeurs et les renvoient lorsque l’on
demande un de ces nombres…Résultat, si un programme utilisant la fonction random() est exécuté
plusieurs fois de suite, les mêmes valeurs seront disponibles, ce qui ôte tout effet de « hasard ».

32
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

La procédure Randomize() donne l’ordre au système de recalculer toutes les valeurs de la


liste de nombres pseudo-aléatoires prédéfinis en se basant sur une graine (encore appelée seed) qui
peut être une valeur choisie arbitrairement ou qui est généralement calculée à partir de l’heure
système courante…Résultat, votre programme a l’air plus réaliste, car plus « hasardeux ».

Bon, si vous n’avez pas compris, pas de souci…Dites-vous que s’il y a la procédure
Randomize(), mieux c’est quand vous employez Random().

Le programme final :

program aleatoire;
uses wincrt;

var n_pile,n_face,n_total,rand:integer;

begin
Randomize;
n_pile:=0;
n_face:=0;
n_total:= 0;
repeat
rand:=random(100);
if (rand<50) then n_pile:=n_pile+1
else
if (rand>50) then n_face:=n_face+1 Figure 10. Simulation de lancer de pièce de monnaie
else
repeat
rand:=random(100);
until (rand<>50);
n_total:=n_total+1;
until (n_total>=100);

writeln('Nombre Piles : ',n_pile);


writeln('Nombre Faces: ',n_face);
end.

33
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

3. Approximation de Pi par la méthode statistique

est un nombre irrationnel dont le nombre de décimales est infini. On désire construire un
programme qui converge vers la véritable valeur de Pi en s’appuyant sur la théorie des grands
nombres. Voici le principe :

Soit a un réel positif. Soit un carré de côté 2a, et un cercle inscrit dans le carré de rayon a.

Laissons tomber dans le carré une goutte d’eau. Quelle est la probabilité que cette goutte
tombe dans le cercle ?

La réponse serait :
( )

La loi des grands nombres appliquée à cette situation nous permet de dire : « Si nous laissons
tomber non pas une, mais des milliards de gouttes dans le carré, et que nous faisons le rapport des
gouttes qui sont tombées dans le cercle, sur les total des gouttes que nous avons laissées chuter dans
le carré, nous avons une excellente approximation de ».

Il suffit donc de multiplier par 4 cette approximation pour avoir une toute aussi excellente
approximation de Pi….

Concevoir un programme qui illustre cette hypothèse. Au début du programme, l’utilisateur


devra préciser le nombre de gouttes qu’il souhaite employer pour son approximation de Pi. Il va sans
dire que plus grand sera ce nombre, meilleure sera l’évaluation de Pi. A chaque itération devra être
affiché :

 Le nombre de gouttes dans le cercle


 Le nombre de gouttes générées au total
 L’approximation courante : la valeur approchée de Pi obtenue par le programme devra être
affichée à chaque itération et avec 10 décimales.

34
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Résolution

Nous allons ici définir un certain nombre de variables de type entier.

 nGen : il s’agit du nombre total de points à générer.


 inC : cette variable nous servira à dénombrer les points générés qui seront dans le cercle.
 outC : nous servira à dénombrer les points générés hors du cercle.

Il est clair que nous devrons avoir la relation : nGen = inC + outC en fin d’expérience.

Voici l’algorithme que nous allons mettre sous code :

 Demander à l’utilisateur le nombre de points qu’il souhaite générer et stocker cette valeur
dans nGen.
 Initialiser les variables inC et outC à 0.
 Répéter ceci :
 Retrancher 1 à nGen.
 Générer 2 nombres au hasard entre 0 et 1. Ces deux nombres constitueront pour nous les
coordonnées x et y d’un point.
 Vérifier si ce point généré est dans le cercle de centre (0.5, 0.5) et de rayon 0.5. Si oui, on
rajoute 1 à inC. Sinon, on rajoute 1 à outC.
 Afficher les informations requises inC, nGen, et l’approximation de PI).

Jusqu’à ce que nGen atteigne 0 (c’est - à - dire que nGen points ont été générés).

35
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Le programme final :

program Evalpi;
uses wincrt;
var inC,outC,nGen:integer;
randX,randY:double;

begin
Randomize;
write('Nombre de generations aleatoires : ');
readln(nGen);
inC:=0;
outC:=0;
repeat
randX:=random(100)/100;
randY:=random(100)/100;
nGen:=nGen-1;
if ((randX-0.5)*(randX-0.5)+(randY-0.5)*(randY-0.5)<0.5*0.5) Then
inC:= inC+1
else
outC:=outC+1;
writeln('Nbre Points dans le cercle: ',inC,' Total : ',(inC+outC));
writeln('Approximation courante : ',(inC/(outC+inC))*4);
writeln;
until (nGen<=0);
end.

Nota : Il est possible que le code fourni ne compile pas. Vous pourrez recevoir une erreur de ce type :

« Must be in 8087 Mode to compile this ».

Ceci signifie tout simplement que vous devrez activez un mode spécial de calcul de votre
processeur avant de pouvoir faire tourner ce code. Ce mode (8087) permet une meilleure gestion des
nombres réels. Pour l’activer, Ouvrez le Menu « Options », puis « Compiler ». Dans la boîte de
dialogue qui s’ouvre, vérifiez que la case « Compiler Settings for » est réglée sur « Windows
targets ». Puis cochez l’option « 8087/80287 » de la partie « Numeric Processing ». Puis validez avec
OK. Le code devrait fonctionner sans problèmes désormais.

36
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

4. Calcul Intégral d’une fonction polynomiale

Voilà sans doute l’un des exercices les plus complexes que je propose dans ce document,
mais qui reste de loin le plus intéressant à étudier, et qui vous fera comprendre beaucoup de choses.

L’objectif est simple : concevoir un programme qui calcule l’intégrale d’une fonction entre
deux bornes réelles a et b que l’utilisateur fixe lui-même. Prendre l’exemple de la fonction f(x)=x².

Résolution

Nous allons dans un premier temps mettre au point un algorithme de calcul, que nous allons
ensuite implémenter (traduire) en Pascal.

La technique que nous allons employer est déjà connue : la méthode des trapèzes. Intégrer
une fonction f entre deux points a et b n’est rien d’autre que calculer l’aire sous la courbe de f entre
ces deux points. Et cette aire peut être approchée par une somme de trapèzes de même hauteur p,
cette valeur p étant un pas de découpage de l’intervalle *a,b+.

La somme des surfaces des trapèzes de hauteur p et de bases f(a+ip),f(a+(i+1)p) permet


d’obtenir une approximation de l’intégrale de f sur *a,b+.

Il faut par ailleurs noter que le résultat trouvé est encore meilleur lorsque le pas est de plus
en plus faible. Nous allons donc exploiter ce critère de convergence pour approcher la solution du
problème.

Nous demandons à l’utilisateur de fournir en entrée les bornes a et b sur laquelle il désire
calculer l’intégrale d’une fonction f prédéfinie. Ensuite, l’utilisateur précise le pas de calcul avec
lequel il désire commencer. Par exemple, pour a=2, b = 10 et un pas p = 1, l’intervalle *a,b+ sera divisé
en (b-a)/p soit 8 trapèzes de hauteur p=1. Si nous calculons l’intégrale en sommant l’aire de ces 8
trapèzes, nous obtenons une certaine valeur approchée de ∫ ( ) ( ). En prenant un pas plus
faible, donc un plus grand nombre de trapèzes, on obtient une valeur encore plus précise. On peut
continuer à diminuer le pas jusqu’à ce que la valeur trouvée à la k-ième itération soit très proche de

37
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

celle trouvée à l’itération précédente…Ce qui implique que l’utilisateur devra préciser à quel niveau
de précision il souhaite arrêter son calcul.

Nous pouvons désormais passer à une implémentation progressive de l’algorithme :

program calcintegral;
uses wincrt;

{Fonction retournant la surface d'un trapèze de bases b1, b2, et de hauteur h}


function tarea(b1,b2,h:real):real;
begin
tarea:=(b1+b2)*(h/2);
end;

{fonction retournant le carré de x : représente la fonction à intégrer}


function carre(x:real):real;
begin
carre:=sqr(x);
end;

{variables globales au programme}


var a,b,p0,epsilon,temp,IP,IA:real;
i:integer;
n_data:longint;

begin
writeln('Programme de Calcul Intégral de f(x) = x^2');
writeln('Entrez la borne inférieure puis la borne supérieure d''intégration');

{on demande à l'utilisateur les bornes a et b d'intégration.


Au cas où il entre une valeur de a plus grande que b, on permute ces valeurs}

readln(a,b);
if a > b then
begin
temp:=a;
a:=b;
b:=temp;
end;

{on demande à l'utilisateur le pas d'intégration.


Au cas où le pas qu'il entre est plus grand que |a-b|, on ramène le pas à |a-b|.}

writeln('Entrez le pas d''intégration');


read(p0);
if p0 > (b-a) then
begin
p0:=(b-a);
writeln('Pas supérieur à l''intervalle d''intégration. Pas redéfini à ',p0);
end;

{on demande à l'utilisateur la précision de calcul souhaitée. Cela constituera le critère d'arrêt des itérations}

38
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

writeln('Entrez la précision sur le calcul souhaitée');


read(epsilon);

{on double le pas entré par l'utilisateur pour se forcer à commencer par ce pas, on fixe IA à 0}
p0:=p0*2;
IA:=0;

{le calcul intégral commence ici, à la condition que la borne a soit différente de la borne b. Sinon, on renvoie 0.}

if a <> b then
repeat
IP:=IA;
p0:=p0/2;
writeln('Le pas de calcul courant vaut ',p0);
n_data:=trunc(((b-a)/p0))+1;
if (a+(n_data*p0))> b then n_data:=n_data-1;
IA:=0;
for i:=0 to n_data-1 do IA:=IA+tarea(carre(a+(i*p0)),carre(a+(i+1)*p0),p0);
until (abs(IP-IA) < epsilon)
else IA:=0;

writeln('La valeur de l''integrale est: ',IA:0:4);


end.

En appliquant ce programme au calcul de ∫ , on obtient la valeur 291.6669, preuve qu’il


fonctionne !

39
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

5. Table de Gauss

La table de Gauss est utilisée en statistiques pour évaluer les probabilités d’occurrence d’un
phénomène caractérisable par une variable suivant une loi normale. L’objectif de cet exercice est de
concevoir un programme qui, lorsqu’il reçoit une valeur t, renvoie p(X<=t).

Résolution

Cela peut paraître au premier abord extrêmement complexe, mais la façon de procéder est
relativement simple, vu que nous avons déjà traité d’un cas similaire presque sans nous en rendre
compte.

Il suffit de savoir que :

| | ∫

Mais avant de continuer, nous allons procéder à une rapide démonstration qui vise à
simplifier cette écriture :

On sait que :

∫ √ .

Cette fonction est appelée intégrale de Gauss. Elle est symétrique, ce qui permet d’arriver à
l’écriture :

∫ ∫ ∫ ∫
√ √ √ √

D’où l’expression finale :

∫ ∫
√ √

Nous pouvons donc poser le problème de cette manière :

| | ∫

40
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

Ce problème est très simple à résoudre, car nous connaissons déjà l’algorithme de calcul de
l’intégrale d’une fonction (voir Exercice 4). Il suffit juste d’adapter la fonction à calculer ici. Ce qui
nous conduit à l’implémentation suivante :

program calcintegral;
uses wincrt;

{fonction retournant la surface d'un trapèze de bases


b1,b2 et de hauteur h}
function tarea(b1,b2,h:real):real;
begin
tarea:=(b1+b2)*(h/2);
end;

{fonction représentant la loi normale à intégrer}


function loinormale(x:real):real;
begin
loinormale:=(exp(-(x*x)/2))/sqrt(2*pi);
end;

{variables globales au programme}


var t,p0,epsilon,IP,IA:real;
isNeg:boolean;
i:integer;
n_data:longint;

begin
writeln('Programme de Calcul Intégral de la loi normale centrée reduite');
writeln('Entrez la valeur t correspondant à la probabilité de l''evènement |X <= t| ');

{on demande à l'utilisateur la valeur de t. Au cas ou elle est negative, on la prend


en signe opposé, et on lui renverra à la fin la valeur de 1 - P|x<=t| }

read(t);
if t < 0 then
begin
t:=-t;
isNeg:=true;
end
else isNeg:=false;

{on demande à l'utilisateur le pas de calcul qu'il souhaite employer au départ.


Ce pas sera modifié pendant l'execution du programme}
writeln('Entrez le pas d''intégration');
read(p0);

{on demande à l'utilisateur la précision de calcul.


Cela servira de critère d'arrêt des iterations}
writeln('Entrez la précision sur le calcul souhaitée');
read(epsilon);

p0:=p0*2;
IA:=0;
41
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

{le calcul integral commence ici}


repeat
IP:=IA;
p0:=p0/2;
writeln('Le pas de calcul courant vaut ',p0);
n_data:=trunc((t/p0))+1;
if ((0+n_data*p0))> t then n_data:=n_data-1;
IA:=0;
for i:=0 to n_data-1 do IA:=IA+tarea(loinormale((0+i*p0)),loinormale(0+(i+1)*p0),p0);
IA:=IA+0.5;
if isNeg then IA:=1-IA;
until (abs(IP-IA) < epsilon) ;

writeln('La valeur de l''integrale est: ',IA:0:5);


end.

Ici un exemple de calcul de P|X <= 2.45|. Obtient la valeur 0.9926, et la table de Gauss donne
0.9929…Résultat acceptable donc !

42
Quelques aspects d’algorithmique de base et implémentation en Turbo Pascal

En conclusion…

La compilation d’exercices qui ont été traités tout au long de ce document devrait vous
permettre de vous exercer en Pascal. Vous devrez désormais être capables de résoudre sans aide
particulière la plupart des problèmes traités dans la première partie. Ceux de la seconde partie sont
volontairement plus complexes, mais sont d’excellents cals d’études pour les mordus de calculs, et
sait-on jamais, leur permettront de mieux saisir les concepts itératifs, d’approximations, etc.

Les thèmes abordés ne couvrent pas tout le champ d’investigation de la programmation,


hélas, mais vous confèrent une base solide pour attaquer les autres. Certains aspects assez
élémentaires n’ont pas été abordés, notamment les algorithmes de tri de données, qui sont
incontournables. Mais il ne s’agit que d’une version première du présent document, que je pourrai
éventuellement mettre à jour en intégrant ces nouveaux aspects.

Je reste conscient que les codes sources que j’ai présentés ne sont pas forcément les
meilleurs, et certains peuvent être optimisés. Je reste ouvert à toute critique objective, et également
aux questions de compréhension. N’hésitez surtout pas !

En espérant que vous en ferez bon usage !

43