CMPS 144 Spring 2020
Prog. Assg. #1: 3-Color Partitioning
Due: 11:59pm, Monday, February 24

This assignment builds upon the programming concepts that were the subjects of Labs #2 and #3 in CMPS 144L.

Provided is an unfinished abstract Java class, Partitioner3Color, which is very similar to the RWB_Partitioner class that you were to have completed in Lab #2. It has three methods, partition(), partition2(), and partition3(), each having as its purpose to rearrange the elements in an array of type char[] so that all elements classified as RED come first, followed by those classified as WHITE, followed by those classified as BLUE. Such an operation is commonly known as partitioning, which explains why the methods are named as they are. The partition() method and its companion, loopInvariant(), are complete; it is left for you to supply the bodies of partition2(), partition3(), and their companions loopInvariant2() and loopInvariant3(), respectively. Of course, you are expected to use partition() and loopInvariant() as models for the methods that you are to complete.

Like partition(), the partition2() and partition3() methods should rearrange the array elements via a sequence of calls to the swap() method. What distinguishes the three methods from each other is that their loops maintain different invariants, as follows:

Loop Invariant of partition()
 0             rw            wq            wb            N
+-------------+-------------+-------------+-------------+
|   all RED   |  all WHITE  |      ?      |  all BLUE   |
+-------------+-------------+-------------+-------------+

Loop Invariant of partition2()
 0             rw            wb            bq            N
+-------------+-------------+-------------+-------------+
|   all RED   |  all WHITE  |   all BLUE  |      ?      | 
+-------------+-------------+-------------+-------------+

Loop Invariant of partition3()
 0             rq            rw            wb            N
+-------------+-------------+-------------+-------------+
|   all RED   |      ?      |  all WHITE  |  all BLUE   |
+-------------+-------------+-------------+-------------+

The partition() and partition2() methods have the same loop invariants as in Lab #2, so if you spent time on the latter during that lab session, the work that you did then might be useful to you here. The partition3() method is brand new. In developing the code for that method, you are encouraged to find a solution that never swaps elements at distinct locations and having the same color. (This is worth a couple bonus points.)

One change from the code you worked with in Lab #2 is that the companion methods used for testing the loop invariants now have four parameters rather than only two, so that they no longer refer directly to the instance variables that indicate the boundaries between adjacent segments of the array.

At the class level, what is different from Lab #2 is that Partitioner3Color is an abstract class, meaning that one or more of its methods is declared to be abstract (and thus have no body). Specifically, the abstract methods are isRed(), isWhite(), and isBlue(). The idea is that any number of child classes can be developed, each having the ability to partition arrays of type char[] according to its own unique criteria by which to classify characters into the categories RED, WHITE, and BLUE.

Because every child class of Partitioner3Color inherits all its instance variables and methods, including the three methods that carry out partitioning, all that any such child class needs to supply is its own versions of the methods isRed(), isWhite(), and isBlue().

This concept should be familiar to you, as in Lab #3 you were to have developed classes StoppingCouner and WarningCounter, both children of the abstract class BoundedCounter, which left to its children the job of providing concrete versions of the incrementFromMax() and decrementFromMin() methods.

You are to develop two child classes of Partition3Color, one called PartitionerUpperLower and the other PartitionerDigitLetter. They are to classify values of type char as follows:

PartitionerUpperLower PartitionerDigitLetter
REDupper case letters ('A'..'Z') digits ('0'..'9')
WHITElower case letters ('a'..'z') letters ('A'..'Z' and 'a'..'z')
BLUEall othersall others

In implementing the methods that classify char values as either RED, WHITE, or BLUE, you may find the following methods (from the class java.lang.Character) useful: Character.isDigit(), Character.isLetter(), Character.isLowerCase(), and Character.isUpperCase().

You should find the Java application Part3ColorTester useful in testing your work. A sample user-program dialog is shown below.


Program Submission

Using the file submission system (see link on course web page), you are to submit three Java source code files to the prog1_dir folder: Partitioner3Color.java, PartitionerUpperLower.java, and PartitionerDigitLetter.java.

Dialog with Part3ColorTester

Welcome to the partitioner tester program!
Enter 1 to test PartitionerUpperLower
Enter 2 to test PartitionerDigitLette
> 2
Enter # of RED elements to place into the array: 4
Enter # of WHITE elements to place into the array: 7
Enter # of BLUE elements to place into the array: 3
Enter (int) seed for pseudo-random # generation: 27

About to call partition() on this array:
(Ug8,J8_5bOzx4

After calling partition(), we have:
Partitioned array: 4885xJgzUbO_,(
RED segment [0,4): 4885
WHITE segment [4,11): xJgzUbO
BLUE segment [11,14): _,(
# color tests: 27
# swaps: 7

About to call partition2() on this array:
(Ug8,J8_5bOzx4

After calling partition2(), we have:
Partitioned array: 8854gUbOzxJ(,_
RED segment [0,4): 8854
WHITE segment [4,11): gUbOzxJ
BLUE segment [11,14): (,_
# color tests: 27
# swaps: 15

About to call partition3() on this array:
(Ug8,J8_5bOzx4

After calling partition3(), we have:
Partitioned array: 4588zJgxUbO,_(
RED segment [0,4): 4588
WHITE segment [4,11): zJgxUbO
BLUE segment [11,14): ,_(
# color tests: 36
# swaps: 6

Goodbye.