Une solution de l'examen d'informatique du 10 janvier 2002
(DEUG S1 MIAS+MASS)

EXERC ICE

Les deux premiers paramètres de la procédure bizarre sont des paramètres "passés par adresse" et le dernier est un paramètre "passé par valeur". On peut donc, avec les mêmes résultats, remplacer les 4 lignes de la procédure par les 2 lignes  suivantes :
    x:=n+1 ;
    y:=x+3 ;


Première ligne du programme :
Deuxième ligne :
Troisième ligne :
En conclusion, le programme affichera :
 
     h     i     k

     1     5     2
     6     9     5

PROBLEME

Voici un exemple de programme complet qui répond aux questions. On remarquera que toutes les variables dont a besoin un sous-programme sont passées en paramètres de ce sous-programme.

program E01solution ;

(* Laisser les deux lignes suivantes pour Delphi *
(* les retirer pour GPC ou Turbo Pascal *)
   {$APPTYPE CONSOLE}
   uses sysutils;


TYPE POINT = array[1..2] of integer ;
     FIGURE = array[1..999] of POINT ;

VAR Fig : FIGURE ;
    n : integer ;
    choix : integer ;
 
(* première partie *)

PROCEDURE CREER(Var F:FIGURE; m:integer) ;
Var i, j : integer ;
Begin
for i:=1 to m do
    for j:=1 to 2 do
        F[i,j]:=random(41)-20 ;
End ;

PROCEDURE LISTER(F:FIGURE; taille:integer) ;
Var i : integer ;
Begin
for i:=1 to taille do
    writeln(i:3,': (',F[i,1],',',F[i,2],')') ;
End ;

FUNCTION AVANT(P,Q:POINT): boolean ;
Begin
AVANT:= ( (P[2]>Q[2]) or ((P[2]=Q[2]) and (P[1]<Q[1])) ) ;
End ;

PROCEDURE ECHANGE(Var F:FIGURE;i,j:integer);
Var P : POINT ;
Begin
P[1]:=F[i,1] ;   P[2]:=F[i,2] ;
F[i,1]:=F[j,1] ; F[i,2]:=F[j,2] ;
F[j,1]:=P[1] ;   F[j,2]:=P[2] ;
(* N.B. on aurait pu utiliser une affectation globale :
            P:=F[i]; F[i]:=F[j]; F[j]:=P                *)
End ;

PROCEDURE CLASSER(Var F:FIGURE; taille:integer);
Var i, j : integer ;
Begin
(*tri brutal*)
for i:=1 to taille-1 do
    for j:=i+1 to taille do
        if AVANT(F[j],F[i]) then ECHANGE(F,i,j) ;
End ;

FUNCTION HAUTGAUCHE(F:FIGURE; taille:integer): POINT ;
Var P : POINT ;
    i : integer ;
Begin
P:=F[1] ;
for i:=2 to taille do
    begin
    if P[1]>F[i,1] then P[1]:=F[i,1] ;
    if P[2]<F[i,2] then P[2]:=F[i,2] ;
    end ;
HAUTGAUCHE:=P ; (*affectation globale*)
End ;

FUNCTION BASDROITE(F:FIGURE; taille:integer): POINT ;
Var P : POINT ;
    i : integer ;
Begin
P:=F[1] ;
for i:=2 to taille do
    begin
    if P[1]<F[i,1] then P[1]:=F[i,1] ;
    if P[2]>F[i,2] then P[2]:=F[i,2] ;
    end ;
BASDROITE:=P ;
End ;

PROCEDURE AFFICHER(F:FIGURE; taille:integer) ;
Var gauche, droite, bas, haut : integer ;
    P : POINT ;
    x, y : integer ;
    position : integer ;
Begin
(* cette procédure ne marche que si la figure est triée  ! *)
P:=HAUTGAUCHE(F,taille) ;
gauche:=P[1] ;
haut:=P[2] ;
P:=BASDROITE(F,taille) ;
droite:=P[1] ;
bas:=P[2] ;
position:=1 ;
for y:=haut downto bas do
    begin
    for x:=gauche to droite do
        if (F[position,1]=x) and (F[position,2]=y)
           then begin
                write('#') ;
                position:=position+1 ;
                end
           else write('-') ;
    writeln ;
    end ;
End ;

(* deuxième partie *)

BEGIN
Repeat
  (*saisie du nombre de points*)
  repeat
    write('combien de points dans la figure ? ') ;
    readln(n) ;
    until (n>1) and (n<1000) ;
  (*création aléatoire d'une figure à n points*)
  CREER(Fig,n) ;
  (*afficher la liste des coordonnées des points de la figure*)
  LISTER(Fig,n) ;
  readln ; (* pause entre les deux affichage *)
  (*trier la figure*)
  CLASSER(Fig,n) ;
  (*afficher la figure*)
  AFFICHER(Fig,n) ;
  (*reprendre sur une autre figure ou s'arrêter*)
  writeln ;
  writeln('-1- recommencer avec une autre figure,') ;
  writeln('-0- arreter.');
  write('? ') ;
  readln(choix) ;
  until choix=0 ;
END.