soluce5b.adb

Pour télécharger ce fichier, clic-droit sur ce lien : soluce5b.adb
with Gada.Text_IO ;
with Villes ;

procedure Mission5b is
   
   package V renames Villes ;
   package Txt renames Gada.Text_IO ;
   
   procedure Afficher_Ville(Nom_Ville : String ; Fiche_Ville : V.T_Fiche) is
   begin
      Txt.Put_Line(Aff => Nom_Ville & " (" & Integer'Image(Fiche_Ville.Code_Postal) & 
		   " )  Pop 2010 = " & Integer'Image(Fiche_Ville.Pop2010) & " hab.") ;
   end Afficher_Ville ;
   
   
   -- Afficher toutes les communes d'une département
   procedure Afficher_Departement(Dept : Integer) is
      Fiche : V.T_Fiche ;
   begin
      -- Parcourir toutes les villes
      for Numv in 1..V.Nb_Villes loop
	 
	 Fiche := V.Fiche_Ville(No => Numv) ;
	 
	 -- et ne sélectionner que celles qui sont dans le département cherché
	 if Fiche.Departement = Dept then
	    Afficher_Ville(Nom_Ville => V.Denomination(Numv), Fiche_Ville => Fiche) ;
	 end if ;
      end loop ;
   end Afficher_Departement ;
   
   
   --- Trouver la ville la moins peuplee
   function Desert return Integer is
      No_Ref : Integer ;
      Pop_Ref : Integer := 999999999 ;
      Fiche : V.T_Fiche ;
   begin
      -- Parcourir toutes les villes et les comparer à la ville de référence la moins peuplée jusqu'ici.
      for Numv in 1..V.Nb_Villes loop
	 
	 Fiche := V.Fiche_Ville(No => Numv) ;
	 -- A-t-on une ville moins peuplée que la référence ?
	 if Fiche.Pop2010 < Pop_Ref then
	    -- Oui, on mémorise cette ville et sa population
	    Pop_Ref := Fiche.Pop2010 ;
	    No_Ref := Numv ;
	 end if ;
	 
      end loop ;
      return No_Ref ;
   end Desert ;
   
   --- Exercice suprême
   function Fiche_Departement (Num_Dept : Integer) return V.T_Fiche is
      Resultat : V.T_Fiche ;
      
      -- Population de la ville la plus peuplée
      Max_Pop : Integer := 0 ;
      
      -- Somme pondérée des coordonnées
      Somme_Long : Float := 0.0 ;
      Somme_Lat  : Float := 0.0 ;
      
      -- Fiche de chaque commune
      Fiche : V.T_Fiche ;      
   begin
      
      -- Initialisation
      Resultat := (Departement => Num_Dept,
		   Code_Postal => 0,
		   Pop2010     => 0,
		   Pop1999     => 0,
		   Surface     => 0.0,
		   Longitude   => 0.0,
		   Latitude    => 0.0,
		   Alt_Bas     => 999999,
		   Alt_Haute   => 0) ;
      
      -- Parcourir toutes les communes du département
      for Numv in 1..V.Nb_Villes loop
	 Fiche := V.Fiche_Ville(No => Numv) ;
	 
	 -- Dans le bon département ?
	 if Fiche.Departement = Num_Dept then
	    
	    -- Ville la plus peuplée : mémoriser son code postal
	    if Fiche.Pop2010 >= Max_Pop then
	       Max_Pop := Fiche.Pop2010 ;
	       Resultat.Code_Postal := Fiche.Code_Postal ;
	    end if ;
	    
	    -- Somme des populations
	    Resultat.Pop2010 := Resultat.Pop2010 + Fiche.Pop2010 ;
	    Resultat.Pop1999 := Resultat.Pop1999 + Fiche.Pop1999 ;
	    
	    -- Somme des surfaces
	    Resultat.Surface := Resultat.Surface + Fiche.Surface ;
	    
	    -- Somme pondérée des coordonnées
	    Somme_Long := Somme_Long + Fiche.Longitude * Fiche.Surface ;
	    Somme_Lat := Somme_Lat + Fiche.Latitude * Fiche.Surface ;
	    
	    -- Altitude min
	    if Fiche.Alt_Bas < Resultat.Alt_Bas then
	       Resultat.Alt_Bas := Fiche.Alt_Bas ;
	    end if ;
	    
	    -- Altitude max
	    if Fiche.Alt_Haute > Resultat.Alt_Haute then
	       Resultat.Alt_Haute := Fiche.Alt_Haute ;
	    end if ;
	 end if ;
	 
      end loop ;
      
      -- Calcul de la moyenne des coordonnées (seulement si le département est "non vide").
      if Resultat.Code_Postal /= 0 then
	 Resultat.Longitude := Somme_Long / Resultat.Surface ;
	 Resultat.Latitude := Somme_Lat / Resultat.Surface ;
      else
	 Resultat.Longitude := 0.0 ;
	 Resultat.Latitude := 0.0 ;
      end if ;
      
      return Resultat ;
   end Fiche_Departement ;
   
   procedure Tester_Departements is
      -- Test ad-hoc pour les département de 31 à 50
      Dept_Debut : constant Integer := 31 ;
      Dept_Fin : constant Integer := 50 ;
      
      Fiche : V.T_Fiche ;
   begin

      for Dept in Dept_Debut..Dept_Fin loop
	 Fiche := Fiche_Departement(Num_Dept => Dept) ;
	 
	 Txt.New_Line ;
	 Txt.Put_Line(Aff => "Departement " & Integer'Image(Dept)) ;
	 Txt.Put_Line(Aff => "   Code postal de la ville principale : " & Integer'Image(Fiche.Code_Postal)) ;
	 Txt.Put_Line(Aff => "   Population totale : " & Integer'Image(Fiche.Pop2010) & " (2010),   " & Integer'Image(Fiche.Pop1999) & " (1999)") ;
	 
	 -- On affiche volontairement la surface comme un entier pour que ce soit plus lisible.
	 Txt.Put_Line(Aff => "   Surface : " & Integer'Image( Integer(Fiche.Surface) ) & "km²") ;
	 Txt.Put_Line(Aff => "   Coordonnées moyennes : " & Float'Image(Fiche.Longitude) & ", " & Float'Image(Fiche.Latitude)) ;
	 Txt.Put_Line(Aff => "   Altitudes extrêmes : " & Integer'Image(Fiche.Alt_Bas) & "m <" & Integer'Image(Fiche.Alt_Haute) & "m") ;
      end loop ;
   end Tester_Departements ;
   
   Ville_Deserte : Integer ;
   
begin
   
   Afficher_Departement(Dept => 44) ;
   
   Ville_Deserte := Desert ;
   Txt.New_Line ;
   Txt.Put_Line("Ville la moins peuplée de la liste : ") ;
   Afficher_Ville( Nom_Ville => V.Denomination(No => Ville_Deserte), 
		   Fiche_Ville => V.Fiche_Ville(No => Ville_Deserte) ) ;
   
   Tester_Departements ;
end Mission5b ;