5.7 Programming with Methods

 

One of the primary reasons for having methods in programming languages is to make it easier to solve complex problems. Having discussed how to create methods, we are now going to look at how we might use methods to create a solution to problems larger than those we have examined previously.

 

To illustrate the use of methods in problem-solving, we will consider a problem related to one proposed by the mathematician Christian Goldbach in 1742, in a letter to Leonhard Euler. In the letter, he made the suggestion that has since come to be known as Goldbach's Conjecture. It states that every even number greater than two can be expressed as the sum of two prime numbers/. Despite the work of many number theorists over the years and even the posting of a $1 000 000 prize for a proof, the conjecture is still unproven (at the time that this was written). Although it has been impossible to prove that the conjecture is true for every even number, it is not too difficult to check the conjecture for a given even number and that is the problem that we are going to examine here.

 

Specifically, we want to develop a program that will repeatedly prompt the user for positive even integer values greater than two and attempt to write each of those numbers as the sum of two primes. The program should continue to read values until the user supplies input of zero. Invalid input should be rejected gracefully.

 

To begin, let us try to develop a strategy. For the moment, we are going to avoid worrying about the details of the program and only focus on its main structure. We want the program to repeatedly read values and, for each value read, see whether or not it satisfies the conjecture. We can refine this analysis into something that looks more like Java (or many other computer languages). Such a form is sometimes called pseudo-code.

 

Example 1

 

A pseudo-code solution to the problem of testing the validity of Goldbach's Conjecture might take the following form.

      

       get first value from user

       while (value != 0)

 

2A prime number is a positive integer that has exactly two distinct factors: one and the number itself.

 

 

{

    test Goldbach's Conjecture on value

    get next value from user

}

 

 

The pseudo-code provides the basis for a main method in our solution to the problem. Some lines of the pseudo-code can be converted directly into single lines in the Java language; others require a number of statements. For the latter type, we can write methods. Thinking this way, we can write the main method.

 

Example 2

 

The pseudo-code of the previous example can be converted to Java as the following main method.

 

public static void main (String[] args)

{

       int value = nextNumber();

       while (value != 0)

       {

             testGoldbach(value);

             value = nextNumber();

    }

}

 

 

Having designed an overall strategy for the solution, we can now focus on the parts that have not yet been analyzed in detail. Here there are two parts that need expansion: the method next Number that reads values and the method testGoldbach that tests the conjecture for a given even number.

 

The method next Number should prompt a user for a value and read a value, rejecting invalid input from the user. The next example shows a possible implementation of this method.

 

Example 3

 

The method nextNumber forces a user to supply a non-negative even number as input. Since the method is only going to be used within this program, we have made its visibility private so that it cannot be called from outside the class in which it is defined.

 

private static int nextNumber ()

{

    int response;

    do

    {

       System.out.println("Give an even integer> 2 ”

                      + "(0 to stop) ”);

       response = In.getlnt();

    }

    while (response<O || response%2!=O || response==2);

    return response;

}

 

 

The method testGoldbach should test the conjecture for a given even number, n, and print either two primes whose sum is n or a message that the conjecture is not true. To see how we might solve the problem in general, it might be useful first to see how we might proceed with a particular case. We do this in the next example.

 

Example 4

 

To determine whether or not the value 12 satisfies Goldbach's Conjecture, we must try to find two primes that sum to 12. To do so, we can break 12 into two parts in various ways, using increasingly larger primes as the first part of the number and testing the differences between these primes and 12 to see if they are also primes. The smallest prime is two, so we start there. The table summarizes our search.

 

 

If we had not had success on the third try, the next pair that we would have tried would have been 7 and 5 but there would be no need to do so because we would have already examined 5 and 7. Thus, once our first part has reached half way to the value being examined, we can quit. If no pair of primes has been found at this point, Goldbach's Conjecture must be false.

 

We incorporate the ideas of Example 4 in our general solution to the problem of testing Goldbach's Conjecture for any given positive even number n. We repeatedly break n up into two parts. The first part should be prime and no more than half the value read. We then test the second part to see if it is also prime. If it is, then the conjecture is true for this value. If not, we continue to look for other possibilities until we find a satisfactory pair of values or we have tried all possible primes for the first part. If we never find a pair that works, then we conclude that the conjecture is false. The next example expresses this in pseudo-code.

 

Example 5

 

A pseudo-code solution to the problem of testing Goldbach's Conjecture for a positive even integer n could take the following form.

 

firstPart = 2

while (conjecture not verified or rejected)

{

    secondPart = n - firstPart

    if (secondPart < firstPart)

       conjecture is false: print message

    else if (secondPart is prime)

       we have verified the conjecture: print parts

         else

       firstPart = next prime after current firstPart

}

 

 

Number theory tells us that there are infinitely many primes so that we can always find a next prime after the current first part. This ensures that the assignment in the last line of code will always be successful.

 

 

We can now convert the pseudo-code to a Java method.

 

Example 6

 

The following Java method tests a positive even integer to see if it satisfies Goldbach's Conjecture. The loop is controlled by a boolean flag done that is initially set to false. It is made true if the conjecture is either verified or refuted. The method assumes that n is a positive even integer greater than two, a condition that is assured by the method nextNumber.

 

private static void testGoldbach (int n)

{

    int firstPart = 2;

    boolean done = false;

    while (! done)

    {

             int secondPart n - firstPart;

       if (secondPart < firstPart)

       {

           System.out.println("Goldbach's Conjecture is “

                      + "false - it fails for II + n);

           done = true;

       }

       else if (isPrime(secondPart))

       {

           System.out.println("Goldbach's Conjecture is true “

                              + "for “ + n + “ = “ + firstPart

                                         + “ + “ + secondPart);

           done = true;

       }

       else

           firstPart = primeAfter(firstPart);

    }

}

 

 

In order to simplify the writing of the main method, we assumed the existence of the methods nextNumber and testGoldbach. Similarly, to simplify the writing of testGoldbach, we have assumed the existence of two other methods: isPrime that tests a number to see if it is prime and primeAfter that returns the next prime following a given value. We have asked you to supply a definition for the method isPrime in the exercises. The next example contains a definition of the method primeAfter.

 

Example 7

 

The method primeAfter shown here returns the next prime following its argument n. It assumes that n is a prime number. If n = 2, the next prime is 3 but otherwise n must be odd and only succeeding odd values are examined.

 

private static int primeAfter (int n)

{

    int value;

    if (n == 2)

       value = 3;

    else

    {

       value = n + 2;

       while (!isPrime(value))

          value += 2;

    }

    return value;

}

 

 

 

A solution should always be well-documented with comments to assist a reader. Comments for a program normally include a description of the purpose of the program, name(s) of the author(s), and the date. Instructors may require additional items such as the course name, your student number, the instructor's name, and so on. Comments for each method normally include a description of its purpose, notes on any parameters, and a description of the value returned (if any). In the next example, we have provided such documentation to an almost complete solution to our problem of testing Goldbach's Conjecture (lacking only the method isPrime that tests a number to see if it is prime). The style that we have used for comments is compatible with the style required by the Javadoc program discussed in Appendix F. Your instructor may suggest another style.

 

Example 7

 

The class GoldBach contains an almost complete solution to the problem posed at the start of this section: to attempt to verify Goldbach's Conjecture for values supplied by a user. One method has been left to be supplied by the reader.

 

/**

* This program repeatedly prompts a user for even integers

* greater than 2, forcing the user to supply valid values.

* The user can terminate the program by supplying a value of

* zero. For each valid input value, the program determines

* whether or not Goldbach's Conjecture holds for that value

* and prints an appropriate message.

* Goldbach's Conjecture states that any even integer greater

* than 2 can be written as the sum of two primes.

* @author        Adrienne Geoffrey

* @version       1.0 July, 2002

*/

class Goldbach

{

   /**

   * Repeatedly get numbers and test each one to see

   * if Goldbach's Conjecture is correct for that value.

   * The sentinel value zero causes the program to stop.

   */

    public static void main (String[] args)

    {

       int value = nextNumber();

       while (value != 0)

       {

           testGoldbach(value);

       value = nextNumber();

       }

    }

   /**

   * Prompt a user for a non-negative even integer other

   * than 2, prompting repeatedly, if necessary, until a

   * valid value is supplied.

   *

   * @return an int - either 0 or an even value> 2

   */

    private static int nextNumber ()

    {

       int response;

       do

       {

           System.out.println("Give an even integer> 2 “

                                         + "O to stop)");

           response = In.getlnt();

       }

       while (response < 0 || response%2 != 0 || response 2) ;

       return response;

    }

    /**

   *Test Goldbach's Conjecture for a given integer and print

   * an appropriate message based on the results of the test.

   *

   *@param    n    an integer assumed to be even and > 2

   */

    private static void testGoldbach (int n)

    {

       int firstPart = 2;

       boolean done = false;

       while (! done)

       {

           int secondPart n - firstPart;

           if (secondPart < firstPart)

           {

               System.out.println("Goldbach's Conjecture is "

                              + "false - it fails for II + n);

           done = true;

           }

           else if (isPrime(secondPart»

           {

               System.out.println("Goldbach's Conjecture is true”

                                 + "for " + n + " = " + firstPart

                                             + " + " + secondPart);

               done = true;

           }

           else

               firstPart primeAfter(firstPart);

       }

    }

    private static boolean isPrime (int n)

    {

       // to come

    }

    /**

   * Find next prime number (in increasing order) after n.

   *

   * @param  n an integer assumed to be a prime number

   * @return  an int - the next prime after n

   */

   private static int primeAfter (int n)

    {

       int value;

       if (n = = 2)

           value = 3;

       else

       {

           value = n + 2;

           while (!isPrime(value))

               value += 2;

       }

       return value;

    }

}

 

 

 

Exercises 5.7

 

l. Find two primes whose sum is equal to the given number.

(a) 4                                (b) 28

 

(c) 38                              (d) 54

 

2. Complete the definition of the method isPrime whose header is

private static boolean isPrime (int n)

The method should return the value true if and only if n is a prime number. You may assume that n > 1. Include comments in your definition.

 

 

3. In addition to the conjecture that we have been examining in this section, Goldbach also proposed that all odd integers greater than six could be written as the sum of three primes. This conjecture, like the one that we have studied, has not yet been proven or disproven. Write a program, similar to the one that we have developed, to test this conjecture.