Problem Statement:
Given two positive integers M and N, find the greatest integer D such that D divides both M and N.
In case you have forgotten, here are a few examples:
- for M=10, N=55, the greatest common divisor D is 5
- for M=72, N=64, the greatest common divisor D is 8
An efficient algorithm to solve this problem hinges on the following observation:
Theorem 1:
For positive integers a,b,d, if d∣a and d∣b, then d∣ax+by for any x,y∈Z.
Proof:
Directly substituting a=kd and b=ld shows that the claim indeed holds. ◼
With this, we can devise an efficient algorithm due to Euclid:
Euclid(M,N)
Input: M,N are integers, M≥N
Output: integer D, the greatest common divisor of M and N
Pseudo-code:
if N==0:
return M
return Euclid(N, M(modN))
Convince yourself that this algorithm works.
Euclid(M,N) eventually terminates with D=xM+yN for some x,y∈Z.
We will prove that it indeed returns the greatest common divisor of M and N.
Theorem 2:
Given integers d,x,y,a,b, if d=ax+by and d divides both a and b, then d is the greatest common divisor of a and b.
Proof:
Suppose that d is not the greatest common divisor of a and b. Hence there is D where D>d such that D divides both a and b. By Theorem 1, D∣ax+by=d, which implies that D≤d, a contradiction. Hence d must be the greatest common divisor of a and b. ◼
Finally, what is the running time of Euclid(M,N)? It is guaranteed that Euclid(M,N) will terminate after O(logN) recursive calls since each call reduces the size of either M or N by half, with each call performs a modular arithmetic which can be done in constant time. The claim below explains the upper bound to the recursive call.
Claim:
If M≥N, then M(modN)<M2
Proof:
N can be either bigger or less than M2, so we have 2 cases to consider:
Case 1: N≤M2
Then we know for a fact that M(modN)<N≤M2.
Case 2: N>M2
Here we have M(modN)≡M−N(modN) and since M−N<M−M2=M2<N we have M(modN)=M−N<M2. ◼
Here is an implementation in C:
/* Recursive greatest common divisor */ int gcd(int M, int N){ if (N>M) return gcd(N, M); if (N==0) return M; return gcd(N, M%N); }
No comments:
Post a Comment