uses crt;
const max=30;
type tMatice = array[1..max,1..max] of integer;
var z: char;
    a,b,m,n,o,p:integer;
    maticeA,maticeB,maticeSoucet,maticeRozdil,E:tMatice;

procedure generuj(var minimum:integer; var maximum:integer);
begin
     write('Zadej dolni mez intervalu: '); readln(minimum);
     write('Zadej horni mez intervalu: '); readln(maximum);
end;

procedure nactiRozmer(var radky, sloupce:integer; popis:char);
begin
     write('Zadej pocet sloupcu matice ',popis,': '); readln(sloupce);
     write('Zadej pocet radku matice ',popis,':   '); readln(radky);
end;

procedure nactiPrvky(sloupce, radky:integer; var matice:tMatice; min,max:integer);
var i,j:integer;
begin
     randomize;
     for i:=1 to sloupce do
         begin
              for j:=1 to radky do
                  matice[i,j]:=random(max-min+1)+min;
         end;
end;

procedure vypisMatici(sloupce,radky:integer; matice:tMatice);
var i,j:integer;
begin
     for i:=1 to sloupce do
         begin
              for j:=1 to radky do
                  write(matice[i,j]:4);
              writeln;
         end;
end;

function jeMozneVypocitat(radkyA,sloupceA,radkyB,sloupceB:integer):boolean;
begin
     jeMozneVypocitat:=false;
     if ((radkyA=radkyB) AND (sloupceA=sloupceB)) then
        jeMozneVypocitat:=true;
end;

procedure soucetMatic(sloupce,radky:integer; matice1,matice2:tMatice; var matice:tMatice);
var i,j:integer;
begin
     writeln('-----------------------------------');
     writeln('Soucet matic:');
     for i:=1 to sloupce do
         begin
              for j:=1 to radky do
                  matice[i,j]:=matice1[i,j]+matice2[i,j];
         end;
end;

procedure rozdilMatic(sloupce,radky:integer; matice1,matice2:tMatice; var matice:tMatice);
var i,j:integer;
begin
     writeln('-----------------------------------');
     writeln('Rozdil matic:');
     for i:=1 to sloupce do
         begin
              for j:=1 to radky do
                  matice[i,j]:=matice1[i,j]-matice2[i,j];
         end;
end;

{ --- cv 12 ---}
function jeMozneNasobit(sloupceA,radkyB:integer):boolean;
begin
     jeMozneNasobit:=false;
     if (sloupceA=radkyB) then
        jeMozneNasobit:=true;
end;

procedure soucinMatic(radkyA,sloupceA,sloupceB:integer; maticeA,maticeB:tMatice; var matice:tMatice);
var i,j,k:integer;
begin
     writeln('-----------------------------------');
     writeln('Soucin matic:');
     for i:=1 to radkyA do
         begin
              for j:=1 to sloupceB do
                  begin
                       matice[i,j]:=0;
                       for k:=1 to sloupceA do
                           begin
                                matice[i,j]:=matice[i,j]+(maticeA[i,k]*maticeB[k,j]);
                           end;
                  end;
         end;
end;

procedure najdiMinimumVeSloupci(radky,sloupce:integer; matice:tMatice);
var i,j,min:integer;
begin
     writeln('-----------------------------------');
     writeln('Minimum ve sloupci:');
     for i:=1 to sloupce do
         begin
              min:=matice[1,i];
              for j:=1 to radky do
                  begin
                       if min>matice[j,i] then
                          begin
                               min:=matice[j,i];
                          end;
                  end;
              write(min:4);
         end;
     writeln;
end;

procedure ulozMatici(radky,sloupce:integer; matice:tMatice);
var soubor:text;
    i,j:integer;
begin
     assign(soubor, 'matice.txt');
     rewrite(soubor);
     for i:=1 to radky do
         begin
              for j:=1 to sloupce do
                  begin
                       write(soubor, matice[i,j]:4);
                  end;
              writeln(soubor);
         end;
     close(soubor);
end;

{hlavni telo programu}
begin
repeat
clrscr;
writeln('Trtkal 2008 - http://fei.trtkal.net');
writeln('-----------------------------------');
begin
     generuj(a,b);

     {nacteni matice A}
     nactiRozmer(m,n,'A');
     nactiPrvky(m,n,maticeA,a,b);

     {nacteni matice B}
     nactiRozmer(o,p,'B');
     nactiPrvky(o,p,maticeB,a,b);

     {vypsani matic}
     writeln('-----------------------------------');
     writeln('Matice A:');
     vypisMatici(m,n,maticeA);
     writeln('-----------------------------------');
     writeln('Matice B:');
     vypisMatici(o,p,maticeB);

     {Zjisteni, zda-li jde matice vypocitat}
     writeln('-----------------------------------');
     if (jeMozneVypocitat(m,n,o,p)) then
         writeln('Matici je mozne vypocitat :-)')
     else
         writeln('POZOR: nelze provest soucet a rozdil matic!');

     {pokud je mozne vypocitat, tak vypocitej matici}
     if (jeMozneVypocitat(m,n,o,p)) then
        begin
             soucetMatic(m,n,maticeA,maticeB,maticeSoucet);
             vypisMatici(m,n,maticeSoucet);
             rozdilMatic(m,n,maticeA,maticeB,maticeRozdil);
             vypisMatici(m,n,maticeRozdil);
        end;

     {pokud je mozne nasobit, tak vypocitej matici}
     if (jeMozneNasobit(n,o)) then
        begin
             soucinMatic(m,n,p,maticeA,maticeB,E);
             vypisMatici(m,p,E);
             najdiMinimumVeSloupci(m,p,E);
             ulozMatici(m,p,E);
        end
     else
         begin
             writeln('-----------------------------------');
             writeln('POZOR: nelze provest soucin matic!');
         end;
end;
writeln('-----------------------------------');
write('Opakovat a/n: ');readln(z);
until (z='n');
end.
