CSE 160
Lab 5 and HW 5
Due Thursday, March 10, 2009


Reading:
Read Ch 5 in the Objects First text .  Work along with it, using BlueJ.

Lab Exercise: TBA
                
HW:  Two projects involving loops, sets, and static methods. (Note: these are not the most efficient methods to solve these problems. They merely illustrate how to think about and use sets.)  Send them to the TA before class on March 10.

A) Sieve of Eratosthenes, using HashSets

1) Look up in a Discrete Math text (or on the internet) about the Sieve of Eratosthenes. Our plan for finding primes is: Initially all numbers from 2 to N are candidates and your set of primes is empty. As long as you have any candidates, choose the smallest candidate and call it p.  Put p into your set of primes. Make a set called multiples of all the integer multiples of p from 1*p up to N*p. Remove all the multiples from the set of candidates (which is a set difference operation: candidates = candidates-multiples).

2) Look at the JavaDocs for the class HashSet, especially the add(), isEmpty(), contains(), remove(), and removeAll() methods. Think about how they can be used in implementing the Sieve algorithm. Notice that HashSet does not have a method for getting its smallest element. We should not expect it to, because in general a set can have any kind of element, not necessarily elements with an ordering, so "smallest" is not defined.

3) Look at the JavaDocs for Math, and observe that its methods are static. They are not invoked on an instance of anything. They are invoked with the class name. For example, to use the absolute value function, we can write int x = Math.abs(-3); The Math class is a way to package groups of useful functions that are not associated with particular instances of anything. We will create such a class with static methods for finding the largest and smallest element of a set of integers. Call the class Search. It has no constructors as it is just a holder for static methods. It will include a method with this signature for largest() and a similar one for smallest()
               public static int largest(Set<Integer> set)
This will take any kind of Set of Integers as its argument, which includes the type HashSet. Below is the algorithm for finding the largest. It is an exhaustive search through the elements of the set. We initialize the answer to something small, e.g., zero. Then try each element in turn, and if it is larger than the largest we found so far, we remember it as the largest. After going through the whole list, we must have found the very largest:
       biggest = 0
       for x in the set
              if (x>biggest) biggest=x
       return biggest

The for-each loop in Java will work with any kind of Set.

A similar algorithm finds the smallest element of a set, but we must initialize its answer variable to something very large. A number like two billion will work fine. If you want the absolutely largest or smallest possible value, look in the JavaDocs for Integer.MAX_VALUE

4) If the above is working, You should be able to create a set and find its largest or smallest element with a Test class like this:

import java.util.HashSet;

public class Test
{
    public Test()
    {
        HashSet<Integer> example = new HashSet<Integer>();
        example.add(7);
        example.add(9);
        example.add(3);
                                // create set {3, 7, 9}
        System.out.println(Search.largest(example));   // should print 9
        System.out.println(Search.smallest(example));  // should print 3
    }
}


5) Write a Sieve class with a HashSet<Integer> field called primes, which has three methods:
You can use the debugger to step through your loop and check it generates in order: 2, 3, 5...  You can then test it further by computing all the primes under 20 if you temporarily include a line printPrimes(); at the end of the constructor. It is OK if they are printed out in a strange order, because the HashSet iterator does not know what order you want.

Send your .jar file to the TA and include in your email the answer to this question: What is the largest prime under 10000?


B) A Finite Sequence


Consider this sequence: 1,3,4,5,6,7,8,9,10,12,15,17,19,21,24,25,...   What is its final term?

It starts with 1. If a given term is n, the next term is obtained by adding to n the smallest positive integer sharing no digit with n. The sequence will end when you reach a number containing all the digits from one through nine, as then there is no next term by the definition.

As we will need to find the smallest element of a set, we can reuse the Search class from above. To do so, import that project into this project, and delete all its classes except Search.

Define a class Term, which holds a general term. It turns out that an integer field can hold the value of the term, because the sequence terminates before two billion. It should have the following methods:
Define class Test with argument N, to print out the first N terms.
        Term t = new Term();
        for (int i=1; i<N; i++) {
            System.out.println(t.getValue());
            t = t.nextTerm();
        }
Verify that you can replicate the initial sequence above. Following the execution with the debugger might be useful.

Define a class LastTerm to find the last term, by generating new terms until null is reached, then returning the last non-null term found. (This takes about five minutes on my PC.)

Send your .jar file to the TA and include in your email the answer to this question: What is the last term?