void factor (natural n)
{// Prints the sequence of prime factors of n to System.out, one per line
// Special cases: outputs empty sequence if n is 0 or 1
if (n <= 1) return;
natural d = 2;
while ((n % d) != 0) && (d < n)) {
if (d*d > n) d = n;
else d++;}
System.out.println (d);
factor (n/d);}
factor
on input n = 60?
2
2
3
5
if
statement in the
while
loop.
The goal of the entire loop is to increase d until it is the smallest prime factor of n. If d*d is greater than n, it must be that every number in the range from 2 through √n has been tested as a possible divisor of n and been found not to be such a divisor. So n must be a prime number, and is its own least prime divisor. We set d to n and skip the other values of d between √n and n, saving time.
factor
only output prime numbers? (Hint: Suppose that
x % d is 0 and d has a divisor e with e > 1. What is x % e?)
Note that the output is always the natural d, and is always output immediately after the while loop terminates. By the condition of the while loop, this can only happen when d divides n and/or is equal to n. If d is equal to n when the loop ends, n (and therefore d) must be prime, because d has passed through every value from 2 thorugh √n and failed to divide n each time. (Note that if the if clause is ever executed, n must be prime.) If d is some other number, we show that it cannot have a proper divisor e with 1 < e < d. Suppose, to get a contradiction, that it does. This e must have been a value of d at some point, because the if clause has never been executed and so d has gone by ones from 2 to its current value. But (following the hint) e must divide n because e divides d and d divides n. So we would have dropped out of the while loop at that point, but we didn't, so there is a contradiction. Since d cannot be composite, and must be at least 2 (since it changes only by either increasing by one or by being set to n, which by this point is at least 2), it is prime.
factor(x)
multiply together to
give x?
Here we assume that the recursive call in In general with Java integer division (the "/" operator), the identity
x = y*(x/y) is not true. But it is true when y divides x evenly. Here we
know that d divides n evenly because of the while loop, which can only
terminate with d dividing n or d ≥ n (where d > n can never happen
because d only changes by being increased by one or set to n).
factor(x)
, to
factor(x/d)
, causes the correct behavior according to
factor
's specification. So it outputs a series of zero or more
naturals, one per line, that multiply to x/d. The output of
factor(x)
is the final value of d, followed by these numbers, so
the product of the numbers output is d*(x/d).
First, we should make sure that the loop cannot go on forever. When the
loop starts, d is 2 and n is at least 2. Then d is either increased by 1 or
set to n, until it divides n or equals n. Even if it is never a proper divisor
of n, it will eventually reach n and the loop will end.
One of the versions of the fifth Peano Axiom in Section 4.1 says that a
recursive algorithm, which only calls itself on x-1 when running on x, must
terminate. This is actually a different situation because the argument is not
necessarily decreasing by 1 each time. But it is getting smaller each
time, because d is always at least 2 and we replace n by n/d. A sequence of
naturals that gets smaller at each step must eventually reach 0, and when the
method is called on an argument of 0 it terminates without recursion. Later
we will use Strong Induction to prove termination of this method more formally.
Last modified 8 March 2006