program Studenti;
{esempio di gestione di un archivio studenti in memoria centrale}
const NumStud=2;
type Nat = 0..MaxInt;
     Index = 1..NumStud;
     Materie = (Analisi,Progr, Lab2, ASD, MatDiscreta);
     Voto = 17..31;
     ListaEsami = array [Materie] of Voto;
     Studente = record
                   Nome:string;
                   Matricola:string;
                   AnnoNascita:Nat;
                   Esami:ListaEsami
                end;
     Archivio = array [Index] of Studente;

var  CorsoA :Archivio;

procedure StampaMaterie(M:Materie);
{procedura di stampa per il tipo enumerato Materie}
begin
  case M of
    Analisi : write('Analisi':14);
    Progr:write('Programmazione':14);
    Lab2:write('Laboratorio2':14);
    ASD:write('ASD':14);
    MatDiscreta:write('MatDiscreta':14)
  end
end;{fine della procedura StampaMaterie}

procedure LeggiStudente (var S:Studente);
{procedura di lettura per il tipo record Studente}
var M:Materie;
begin
  with S do
    begin
      writeln('Inserisci il nome dello studente:');
      readln(Nome);
      writeln('Inserisci la matricola dello studente:');
      readln(Matricola);
      writeln('Inserisci l''anno di nascita dello studente:');
      readln(AnnoNascita);
      for M:=Analisi to MatDiscreta do
        begin
           write('Inserisci il voto di ');
          StampaMaterie(M);
          write(':');
          readln(Esami[M])
        end
     end
end; {fine della procedura Leggi Studente}

procedure StampaStudente(S:Studente);
{procedura di stampa per il tipo record Studente}
var M:Materie;
begin
  with S do
  begin
    writeln('Nome : ':17, Nome);
    writeln('Matricola : ':17,Matricola);
    writeln('AnnodiNascita : ':17, AnnoNascita);
    writeln('Votazioni esami ');
    for M:=Analisi to MatDiscreta do
       begin
         StampaMaterie(M);
         write(' : ');
         case (Esami[M]) of
           17: writeln('Da sostenere');
           31: writeln('30 e lode');
           else writeln(S.Esami[M])
         end
       end
    end
end; {fine della procedura StampaStudente}

procedure LeggiArchivio(var Corso:Archivio);
{procedura di lettura per il tipo array Archivio}
var I:Index;
begin
  writeln('Inserisci i voti con le seguenti modalita`:');
  writeln('Se l''esame deve essere sostenuto, inserire 17');
  writeln('Se il voto e` 30 e lode, inserire 31');
  writeln('altrimenti inserire il voto');
  for I:=1 to NumStud do
   begin
     writeln('Preparati ad inserire i dati del ', I, 'esimo studente');
     LeggiStudente(Corso[I]);
   end
end; {fine della procedura LeggiArchivio}

procedure StampaArchivio(Corso:Archivio);
{procedura di Stampa del tipi array Archivio}
var I:Index;
begin
  writeln('Stampa dell''archivio studenti del corso C');
  for I:=1 to NumStud do
   begin
     writeln;
     StampaStudente(Corso[I]);
   end
end;{fine della procedura StampaArchivio}

procedure scambiastu(var s1,s2:studente);
var temp:studente;
begin
   temp:=s1;
   s1:=s2;
   s2:=temp
end;

function findmin(myclass:archivio;inizio,fine:integer):integer;
var temp,i:integer;
begin
   temp:=inizio;
   for i:=inizio+1 to fine do
     begin
     if myclass[i].nome[1] < myclass[temp].nome[1] then
        temp:=i;
     end;
   findmin:=temp;
end;


procedure ordinastu(var myclass:archivio);
var fill,min:integer;
begin
   for fill:=1 to numstud -1 do
     begin
     min:=findmin(myclass,fill,numstud);
     if min <>fill then scambiastu(myclass[min],myclass[fill])
     end
end;

begin {main}
   LeggiArchivio(CorsoA);
   ordinastu(CorsoA);
   StampaArchivio(CorsoA);
   readln;
end. {main}