Najlepiej wszystko sprowadzić do pojedynczego wymiaru...
const
a=1;
b=1;
var
tab:array[a..a+19,b..b+19]of byte;
i,j:word;
wynik:word;
begin
wynik:=0;
for i:=0 to 398 do
for j:=i+1 to 399 do
inc(wynik,byte(tab[(i div 20)+a,(i mod 20)+b]=tab[(j div 20)+a,(j mod 20)+b]));
// if(tab[(i div 20)+a,(i mod 20)+b]=tab[(j div 20)+a,(j mod 20)+b])then inc(count);
end.
Tylko, że powyższa metoda jest dobra, gby masz szeroki zakres mozliwych wartości, jakie może przyjmować każda komórka tablicy. Gdy masz mało komórek, i sporo różnych wartości. Natomiast...
const
a=1;
b=1;
c=1; // dolna granica zakresu
d=49; // górna granica zakresu
type
zakreswartosci=c..d; // czy inny szczęśliwy numerek
var
count:array[zakreswarotsci]of word; // word, bo 20*20 to 400
tab:array[a..a+19,b..b+19]of zakreswartosci;
i,j:word; // indekzy muszą pokrywać... zakreswartosci , a..a+19 , b..b+19;
wynik:integer;
begin
fillchar(count,sizeof(count),0); // czyścim tablice
wynik:=0;
for i:=a to a+19 do
for j:=b to b+19 do
inc(count[tab[i,j]]);
for i:=c to d do
if count[i]<>0 then // albo nawet if count[i]>1 then
inc(wynik,count[i]-1); // why -1, to już musisz sam się domyslić.
end.
... ta metoda juz na pierwszy rzut oka wydaje się troszkę szybsza, ale tylko dla małego zakrseu przyjmowanych przez komórki tablicy wartości. Jest yeż proporcjonalnie pamięciożerna do tego zakresu. Ale za to wydajmośc w stosunku do poprzedniej rosnie, gdy rośnie liczba komórek.