# Project 1: Arrays Unlimited

• Out on: September 17, 2017
• Due by: September 24, 2017 before 10:00 pm
• Collaboration: none whatsoever
• Grading: Packaging 10%, Style 10% (where applicable), Functionality 80% (where applicable)

Projects are designed to test your mastery of course material as well as your programming skills; think of them as “take-home exams” and don’t communicate with anyone about possible solutions. This project focuses on the specification, implementation, and testing of array-like data structures.

## Problem 1: Uninitialized Arrays (20%)

In lecture we derived an algebraic specification for the abstract data type `Array`. I mentioned that it’s easier to specify the ADT if we make sure that instances are initialized to some known value when they are created using the `new` function.

Following the example specification for `Array`, develop a specification for uninitialized arrays. Note that even “uninitialized” arrays still need a length, but they do not have an “initial value” that gets put into every slot of the array by default; without an “initial value” it’s of course difficult to say what the `get` operation should produce if nothing has been assigned to a slot yet.

You will have to introduce at least one new (as in “not there already”) operation; you’ll also have to adjust preconditions and axioms to make things work.

Write up the algebraic specification for this kind of `UglyArray` in the format we used in lecture. Also comment on the differences to `Array` and explain what kind of array you’d rather have in a programming language; feel free to suggest a third option if neither `Array` nor `UglyArray` are up to your standards.

(Remember that answers to “written problems” such as this one should be submitted in your plain text `README` file.)

### Hints

• Your `UglyArray` is not the `Array` ADT we did in lecture; it will require at least one additional operation.

## Problem 2: Flexible Arrays (20%)

Develop an algebraic specification for the abstract data type `FlexibleArray` which is like our original (bounded, initialized) `Array` ADT for the most part except that both its lower and its upper index bound are set when the array is created. Lower as well as upper bound can be any integer, provided the lower bound is less than or equal to the upper bound; both bounds are inclusive.

Write up the specification for `FlexibleArray` in the format we used in lecture. Also comment on the differences to `Array` and explain what kind of array you’d rather have in a programming language; feel free to suggest a third option if neither `Array` nor `FlexibleArray` are up to your standards.

Note: Some programming languages, notably Pascal and Ada, support arrays of this kind instead of the zero-based arrays that are dominant in C and Java.

(Remember that answers to “written problems” such as this one should be submitted in your plain text `README` file.)

### Hints

• A `FlexibleArray` for which the lower bound equals the upper bound has exactly one slot.
• Your `FlexibleArray` is not the `Array` ADT we did in lecture; it doesn’t have to support the exact same set of operations. Feel free to add and remove operations based on the expected functionality of this variation.
• Recall that we strive for concise specifications. Make sure that all the operations you include are actually needed…

## Problem 3: Sparse Arrays (60%)

A sparse array is an array in which relatively few positions have values that differ from the initial value set when the array was created. For sparse arrays, it is wasteful to store the value of all positions explicitly since most of them never change. Instead, we should store values only for the positions that have actually been changed.

For this problem, you’re supposed to write a class `SparseArray` that implements the iterable `Array` interface we discussed in lecture. (You can download the “official” version of the `Array` interface, complete with most excellent `javadoc` comments, from the Piazza post for this project.) Do not modify the `Array` interface in any way! Instead of using a plain Java array like we did for `SimpleArray`, your `SparseArray` should use a linked list of `Node` objects to store values, similar to the `ListArray` from lecture. However, your nodes no longer store just the data at a certain position, they also store the position itself! Here’s a rough outline of how your implementation could work:

• Start with an empty list (instead of the complete list we built in the constructor of `ListArray`).
• For `put`, check if the relevant position has been modified before (meaning a `Node` object exists for that position); if not, add a `Node` to the list for the position and its new value; otherwise update the correct `Node` to the new value.
• For `get`, check if the relevant position has been modified before; if not, return the default value; otherwise, return the value found in the relevant `Node` object.

Important: Your `Node` class must be nested inside your `SparseArray` class with `private` visibility! Clients should not be able to “touch” `Node` objects in any way!

(Don’t forget to add proper `javadoc` comments for your `SparseArray` class; in particular, include advice for clients trying to decide between the regular `SimpleArray` implementation and your new sparse implementation.)

### Testing

As part of Homework 2 we gave you a program called `PolyCount` that could be used to test the basic operation of a number of different `Counter` implementations. For this project, we’re giving you a similar program called `PolyArray` that can be used to test array implementations (some of the details are a bit more complex for technical reasons, but you don’t need to understand those for now). However, `PolyArray` is far from complete regarding test cases:

• the code in `testNewLength` and `testNewGet` only covers the first two axioms of the specification
• the code in `testNewLengthWrong` only covers the first precondition of the specification

You need to modify `PolyArray.java` to add more test cases so that all axioms and preconditions will be tested. Of course, you should also use `PolyArray` to test your new `SparseArray` code: Once you’re done with `PolyArray` all three implementations should be fully tested when the program is run.

### Hints

• Your iterator for `SparseArray` doesn’t have to be particularly efficient; indeed, it’s rather tricky to make it fast, so don’t try. (Or rather: Only try if you’re bored!)
• Think about this: Someone creates a `SparseArray<Integer>` with an initial value of 1. Then they put a few numbers different from 1 into the array. For example, the value of slot 4 might be 18. Now what should happen for `put(4, 1)`? What should the state of the sparse array be if all elements got changed to something other than the initial value, and then changed back again?
• Testing a precondition means testing that the correct exception is thrown when a bad parameter is provided.
• Note that the `PolyArray` we gave you doesn’t test iterators at all; it probably should since all array implementations (the ones we gave you and the one you wrote yourself) support iterators…
• Ensure that the version of your code you hand in does not produce any extraneous debugging output anymore!

## Deliverables

You must turn in a gzip-compressed tarball of your project; the filename should be `cs226-assignment-number-name.tar.gz` with `number` replaced by the number of this project (see above) and `name` replaced by the first part of the email address you used to register on Piazza. (For example, Peter would use `cs226-assignment-3-phf.tar.gz` for his submission of Project 3.) The tarball should contain no derived files whatsoever (i.e. no `.class` files, no `.html` files, etc.), but should allow building all derived files. Include a plain text `README` file (not `README.txt` or `README.docx` or whatnot) that briefly explains what your programs do and contains any other notes you want us to check out before grading; your answers to written problems should be in this file as well. Finally, make sure to include your name and email address in every file you turn in (well, in every file for which it makes sense to do so anyway)!

For reference, here is a short explanation of the grading criteria; some of the criteria don’t apply to all problems, and not all of the criteria are used on all projects.

Packaging refers to the proper organization of the stuff you hand in, following both the guidelines for Deliverables above as well as the general submission instructions for projects.

Style refers to Java programming style, including things like consistent indentation, appropriate identifier names, useful comments, suitable `javadoc` documentation, etc. Many aspects of this are enforced automatically by Checkstyle when run with the configuration file available on Piazza. Style also includes proper modularization of your code (into interfaces, classes, methods, using `public`, `protected`, and `private` appropriately, etc.). Simple, clean, readable code is what you should be aiming for.

Testing refers to proper unit tests for all of the data structure classes you developed for this project, using the JUnit 4 framework as introduced in lecture. Make sure you test all (implied) axioms that you can think of and all exception conditions that are relevant.

Performance refers to how fast/with how little memory your program can produce the required results compared to other submissions.

Functionality refers to your programs being able to do what they should according to the specification given above; if the specification is ambiguous and you had to make a certain choice, defend that choice in your `README` file.

If your programs cannot be built you will get no points whatsoever. If your programs cannot be built without warnings using `javac -Xlint:all` we will take off 10% (except if you document a very good reason; no, you cannot use the `@SuppressWarnings` annotation either). If your programs fail miserably even once, i.e. terminate with an exception of any kind, we will take off 10% (however we’ll also take those 10% off if you’re trying to be “excessively smart” by wrapping your whole program into a universal try-catch).