CS 5 Fall 2009
Short Assignment #5
Due Monday, October 5

The Counter class that we saw in lecture has a method, tick, which increments the counter and wraps the counter's value back to 0 if incrementing causes the counter to hit its upper limit.

Your job is to add to the Counter class a method, advance that takes one parameter, an int. A call to advance adds the value of the parameter into the value of the counter. For example, if c references a Counter object, then the following would be equivalent:

c.advance(4); and c.tick(); c.tick(); c.tick(); c.tick(); and for (int i = 1; i <= 4; i++) c.tick(); Similarly, if we had an int n whose value was nonnegative (i.e., 0 or positive), the following would be equivalent: c.advance(n); and for (int i = 1; i <= n; i++) c.tick();

You might think that you could just write the body of the advance method as a for-loop that calls tick the right number of times. This approach suffers from two problems. First is that it is quite inefficient if the parameter given in a call of advance is large: you'd end up calling tick that many times.

The second reason is more serious: the parameter to advance is allowed to be negative. In this case, the counter should run backward. What would happen if you ran the following for-loop when n is negative?

for (int i = 1; i <= n; i++) c.tick(); Answer: the loop would iterate 0 times, and the counter would not change at all. We want the counter to be able to decrease. Furthermore, we want it to wrap around properly. For example, suppose that c references a counter with a limit of 5 (so that it could take on the values 0, 1, 2, 3, or 4) and a current value of 2. Suppose further that we call c.advance(-3). Then after the call, the counter should have the value 4. Why 4? Think of it this way: if the counter had the value 4 and we called c.advance(3), it would end up with the value 2.

Now that we've ruled out using a for-loop, think about using the modulus operator (%). Using our example of a counter with limit 5 and value 4, observe that (4 + 3) % 5 gives 2: the same value as advancing by 3.

So it seems that the modulus operator is great here, and it is. Except that there's one other problem. If you mod a negative number, you might get a negative number:

A Counter should never have a negative value, so if you get a negative value after modding, you need to correct it to make it positive. Using our example counter with a limit of 5, observe that if you get the value -1 after modding, you really want your counter to have the value 4; if you get -2, you really want 3; if you get -3, you really want 2; and if you get -4, you really want 1. There's a very simple pattern here that you can easily exploit in your program with simple arithmetic.

So, to recap, your advance method needs to first update the counter's value by performing a mod operation that uses the current counter value, the amount to advance by, and the counter's limit. Then, if the new value is negative, the method needs to adjust it to make it the appropriate positive value. You should be able to write the body of advance in three lines of Java, plus comments.

Modify the Counter class to add the advance method, and modify the CounterDriver class to show some calls of advance. Make sure that your calls demonstrate that advance does the right thing when

The easiest way to do this is to just hard-code the amounts to advance by. For example, you could add the following lines after the for-loop: c1.advance(3); // positive advance, no wraparound: value goes to 3 c1.show(); System.out.println(); You could follow this set of three lines by three more sets of similar lines that demonstrate the cases. Just add code to both classes; do not remove any code.

Hand in printouts of your Counter and CounterDriver classes, along with the output of running the program.


Back to Short Assignments
Thomas H. Cormen <thc@cs.dartmouth.edu>
Last modified: Thu Oct 1 16:10:20 2009