On this page:
Problem 1: Road Trip
Problem 2: Working with Custom Constructors, A Taste of Equality

Assignment 4: Dynamic Dispatch; Constructors; Structural Equality; Non-structural Equality

Goals: Learn to use custom constructors, determine equality via dynamic-dispatch, and determine non-structural equality.


Be very, very careful with naming! Again, the solution files expect your submissions to be named a certain way, so that they can define their own Examples class with which to test your code. Therefore, whenever the assignment specifies:
  • the names of classes,

  • the names and types of the fields within classes,

  • the names, types and order of the arguments to the constructor,

  • the names, types and order of arguments to methods, or

  • filenames,

...be sure that your submission uses exactly those names.

Make sure you follow the style guidelines that Bottlenose enforces. For now the most important ones are: using spaces instead of tabs, indenting by 2 characters, following the naming conventions (data type names start with a capital letter, names of fields and methods start with a lower case letter), and having spaces before curly braces.

You will submit this assignment by the deadline using the Bottlenose submission system. You may submit as many times as you wish. Be aware of the fact that close to the deadline the Bottlenose system may slow down to handle many submissions - so try to finish early.

There will be a separate submission for each problem - it makes it easier to grade each problem, and to provide you with the feedback for each problem you work on.

The submissions will be organized as follows:

Due Date: Wednesday, May 20th, 10:00pm Eastern

Problem 1: Road Trip

Related files:

The starter file has some helpers that may be useful, although you are not required to use them.

For all questions in this problem, be sure to follow the design recipe carefully:
  • Give sufficient examples of data, and sufficient tests, to test your methods thoroughly.

  • If you find yourself wanting to use a field-of-field, stop. Fill out the template for each method, and figure out another design.

  • Think carefully about how to use dynamic dispatch, and where to define methods, to keep your code as simple and clean as possible.

In this problem, you’re going to help two drivers on a RoadTrip. Every road trip has two drivers, driver1 and driver2, as well as directions, which is a list of Direction. A Direction has a description, and a number of miles. For example, if a direction had the description "make a U-turn" and the number of miles was 20, it would mean that in 20 miles, the driver should make a U-turn. Also, for simplicity’s sake, miles will always be measured with whole numbers in this assignment.

The issue our drivers are facing is that the road trip might be very long, so they want to split up the road trip by changing who is in the driver’s seat every 10 (or 15, or 20, or whatever the given number is) miles. The number of miles is always guaranteed to be positive and a whole number, but those are the only assumptions that can be made about the number. Also, note that driver1 should always be the first driver on the road trip.

Design a method splitUpTrip that transforms a road trip into a list of road trip chunks, based on the given number of miles the drivers want to switch-off. A RoadTripChunk has a driver as well as directions, which is a list of Direction.

For example, imagine that drivers Hazel and Henry are following these directions (with the number of miles given after the direction’s description):
  • Make a left at Alberquerque, 13

  • Make a right at the fork, 2

  • Make a left at the next fork, 3

  • Take the overpass, 45

  • Destination on left, 12

If they wanted to switch who was driving every 15 miles, the split up instructions would look like this, with Hazel as the first driver:
  • Make a left at Alberquerque, 13

  • Make a right at the fork, 2

  • Switch with Henry, 0

Then, with Henry driving:
  • Make a left at the next fork, 3

  • Switch with Hazel, 12

Then, with Hazel driving:
  • Switch with Henry, 15

Then, with Henry driving:
  • Switch with Hazel, 15

Then, with Hazel driving:
  • Take the overpass, 3

  • Destination on left, 12

Note that the drivers have to be informed how long to drive until they need to switch, so those instructions need to become new directions in the list of road trip chunks where appropriate.

Hint: you will certainly need to use at least one accumulator parameter in at least one helper method. There are several valid designs for this problem; work through a wish-list process to figure out what helpers you might want.

Hint: When it comes to naming interfaces and classes for lists, be sure to follow our naming convention, or our tests won’t be able to run properly.

Hint: If you find yourself needing to reverse the order of lists (not all implementations will), it is best to reverse everything at the end once so you don’t need to keep track of whether or not directions and/or road trip chunks are in order as you go.

Hint: Make sure you understand the entire given example. Work through it on paper or a whiteboard until each step of the output is clear.

Hint: When a direction is too long for the current driver to finish, it effectively becomes two directions: the direction to switch drivers when their driving is up, and the original direction minus the distance already travelled. When writing your methods, think carefully about how these "new" directions play into the recursive structure of your code, and what list of directions you want to recur on.

Problem 2: Working with Custom Constructors, A Taste of Equality

A BagelRecipe can be represented as the amount of flour, water, yeast, salt, and malt in the recipe. A perfect bagel results when the ratios of the weights are right:

Design the BagelRecipe class. The fields should be of type double and represent the weight of the ingredients as ounces. Provide three constructors for this class:

Flour and water volumes are measured in cups, while yeast, salt, and malt volumes are measured in teaspoons.

Helpful conversion factors:
  • 48 teaspoons = 1 cup

  • 1 cup of yeast = 5 ounces

  • 1 cup of salt = 10 ounces

  • 1 cup of malt = 11 ounces

  • 1 cup of water = 8 ounces

  • 1 cup of flour = 4 and 1⁄4 ounces

Once you’ve completed the above constructors, you should:
  • Remove as much duplicate code as possible from these constructors.

  • Implement the method sameRecipe(BagelRecipe other) which returns true if the same ingredients have the same weights to within 0.001 ounces.