Наибольший общий делитель (НОД)


Извиняйте, что все написано на Паскале, просто задачка чисто школьная, и со
школьных времен ни разу не пригодилась мне в жизни - поэтому я и оставил ее на
Паскале. Кстати, Паскаль - язык вовсе не плохой, и для описания алгоритмов - очень
даже подходящий. Хотелось бы также отметить что функцию НОД правильно называть
gcd() - Greatest Common Divisor.

program nods;

{ WITH FUNCTIONS }

{ version 1 }
function nod1(a,b:integer):integer;
var k:integer;
begin
    if a>b then k:=a else k:=b;
    while not (((a mod k)=0) and ((b mod k)=0)) do
    begin
       k:=k-1;
    end;
    nod1:=k;
end;

{ version 2 }
{ Алгоритм Евклида }
{ NOD(a,b)=NOD(a-b,b)=NOD(a,b-a) }
{ NOD(a,0)=NOD(0,a),  NOD(0,0)=0 }
function nod2(a,b:integer):integer;
var m,n,k:integer;
begin
    m:=a; n:=b;
    while not ( (m=0) or (n=0) ) do
    begin
        if m>=n then
            m:=m-n
        else
            n:=n-m;
   end;
   if m=0 then k:=n else k:=m;
   nod2:=k;
end;

{ version 3 }
{ NOD(a,b)=NOD(a mod b,b) a>=b }
{ NOD(a,b)=NOD(a,b mod a) b>=a }
function nod3(a,b:integer):integer;
begin
    if a=0 then
        nod3:=b 
    else if b=0 then
        nod3:=a
    else if a>=b then
        nod3:=nod3(a mod b,b)
    else if a<b then
        nod3:=nod3(a,b mod a);
end;

{ WITH PROCEDURES }

{ version 4 }
procedure nod4(a,b:word; var c: word);
begin
    if a>b then nod4(a-b,b,c);
    if a<b then nod4(a,b-a,c);
    if a=b then c:=a;
end;

{ version 5 }
procedure nod5(a,b:word; var c: word);
begin
    if b<>0 then nod5(b,a mod b,c)
    else c:=a;
end;

{ version 6 }
{ Алгоритм Евклида }
procedure nod6(a,b:word; var c: word);
var r:word;
begin
    r:=a mod b;
    while r<>0 do
    begin
        a:=b;
        b:=r;
        r:=a mod b;
    end;
    c:=b;
end;

var x,y:integer;

begin
  x:=63;
  y:=36;
  writeln( nod1(x,y) );
  writeln( nod2(x,y) );
  writeln( nod3(x,y) );
end.