In this programming assignment, you will write a Java program to find the greatest common divisor (abbreviated gcd) of two positive integers. The gcd of two positive integers n and m, written gcd (n,m), is the largest integer that divides both n and m without a remainder. For example, the gcd of 20 and 35 is the integer 5. Consequently, we could write:
gcd(20,35) = 5.
Finding the gcd of two integers is an important task in numerous areas of mathematics. For example, to reduce a fraction to lowest terms, first find the gcd of the numerator and denominator, and then divide the numerator and denominator by the gcd. In a subsequent programming assignment, Program VII (Fraction Calculator), we will be working with objects that represent fractions. We will need to write code to express a fraction in lowest terms!
There is a simple (somewhat naive) algorithm for finding the gcd of
two positive integers. If n and m are the two integers, first determine
which one is the smaller. Call this number factor.
Check to see if factor (evenly) divides each of n and m without a remainder.
If so, then factor is the gcd of n and m. If not, try the integer
factor
- 1 next. If factor - 1 does not (evenly)
divide each of n and m without a remainder, check factor
- 2, and so forth. The first integer encountered that (evenly) divides
n and m without a remainder is the gcd of n and m. (This process will terminate,
of course, since the number 1 will evenly divide m without a remainder.)
Note: We will employ the
language m divides n
when
we really mean that n mod m equals 0.
So, for example "7 divides 21" but "13 does not divide 40."
There is a better algorithm for computing the gcd of two positive integers called the Euclidean Algorithm. The Greek mathematician and philosopher Euclid (c. 350 B.C.E.) described this algorithm in his book The Elements, one of the most influential mathematics textbooks ever written. To explain the algorithm, consider finding the gcd of the integers 30 and 72. By inspection, we see that gcd(30,72) = 6. Dividing 30 into 72, we obtain the equation 72 = 2*30 + 12. Suppose d is an integer that divides both 30 and 72 without a remainder. Since 12 = 72 - 2*30, d must divide 12 without a remainder. Therefore, d must divide both 12 and 30 without a remainder. Conversely, if d is an integer that divides both 12 and 30 without a remainder, then it certainly must divide both 30 and 72 without a remainder since 72 = 2*30 + 12. To sum up, any common divisor of 30 and 72 must also divide 12 and any common divisor of 12 and 30 must also divide 72. Therefore, gcd(30,72) = gcd(12,30). Now just repeat the process! Divide 12 into 30 to obtain the equation 30 = 2*12 + 6. Therefore, gcd(12,30) = gcd(6,12). Since 12 = 2*6 + 0, we can stop the process since we have obtained a remainder of 0. We conclude that gcd(30,72) = gcd(12,30) = gcd(6,12) = 6.
As another example, consider finding gcd(198,252).
252 = 1*198 + 54 (Note that 54 = 252
mod 198; so gcd(198,252) = gcd(198, 54))
198 = 3*54 + 36 (Note that 36 = 198 mod
54; so gcd(198,54) = gcd(54, 36) )
54 = 1*36 + 18 (Note that 18 =
54 mod 36; so gcd(54,36) = gcd(36, 18) )
36 = 2*18 + 0 (Stop! A zero
remainder found.)
Clearly now, gcd(198,252) = 18.
In general, to implement the Euclidean Algorithm, you only need the formula:
If n<m, then gcd(n,m) = gcd(n, m mod n).
How many loop iterations are needed in both algorithms? For the naive algorithm, at most n-1 loop iterations are needed to find the gcd of the integers n and m where n is the smaller of the two integers. The analysis is a little harder in the case of the Euclidean Algorithm. Gabriel Lamé (1795 - 1870), a French mathematician, proved that the number of division steps needed to find the gcd of n and m did not exceed five times the number of decimal digits in the number n, the smaller of the two integers! For simplicity, in this program we will compute the number of loop iterations (as measured by the number of times the body of the loop is executed), rather than the number of divisions.
Sample dialogue:
Welcome to the GCD calculator.
Input
two positive integers:
30
72
The
gcd of 30 and 72 is 6.
The
naive algorithm needed 24 loop iterations.
The
Euclidean algorithm needed 2 loop iterations.
Continue?
Y
Input
two positive integers:
198
252
The
gcd of 198 and 252 is 18.
The
naive algorithm needed 180 loop iterations.
The
Euclidean algorithm needed 3 loop iterations.
Continue?
N
Goodbye. Thank you for choosing the Euclidean package.
Extra Credit: Find the gcd of every pair of integers between 1 and 1000 and report the average number of loop iterations required by the naive algorithm and by the Euclidean Algorithm. Notice that there are 1,000,000 pairs of integers to consider! For this extra credit part, your program should run silently producing no output until it has run all 1,000,000 pairs of integers. It should then report the average number of iterations for the naive algorithm and the Euclidean algorithm. An appropriate place for the report to appear would be after the user enters 'N' when asked whether to continue. The program should then output a message such as:
Computing
the average number of loop iterations for every pair
of
integers between 1 and 1000...(please wait)
and so forth.
What to submit:
The file GCDCalculator.java
to your submit folder.
Among those whom I like or admire, I can find no common denominator, but among those whom I love, I can: all of them make me laugh.
- W. H. Auden,
Dyer's
Hand (1963)