CS 112
Spring 2022

Old version

This is the CS 112 site as it appeared on May 12, 2022.

Problem Set 4

due by 11:59 p.m. on Wednesday, February 23, 2022

Preliminaries

In your work on this assignment, make sure to abide by the collaboration policies of the course.

If you have questions while working on this assignment, please come to office hours, post them on Piazza, or email instructor.

Make sure to follow the instructions outlined at the end of Part I and Part II when submitting your assignment.


Part I

40 points total

Creating the necessary folder

Create a subfolder called ps4 within your cs112 folder, and put all of the files for this assignment in that folder.

Creating the necessary file

Problems in Part I will be completed in a single PDF file. To create it, you should do the following:

  1. Access the template that we have created by clicking on this link and signing into your Google account as needed.

  2. When asked, click on the Make a copy button, which will save a copy of the template file to your Google Drive.

  3. Select File->Rename, and change the name of the file to ps4_partI.

  4. Add your work for the problems from Part I to this file.

  5. Once you have completed all of these problems, choose File->Download->PDF document, and save the PDF file in your ps4 folder. The resulting PDF file (ps4_partI.pdf) is the one that you will submit. See the submission guidelines at the end of Part I.

Problem 1: Understanding and using inheritance

10 points total; individual-only

Imagine that you wanted to capture information about a collection of different types of vehicles (cars, trucks, motorcycles, etc.). To do so, you could use inheritance to create a collection of related classes whose inheritance hierarchy looks like this:

We have provided an implementation of most of these classes in this folder, and we encourage you to review the provided files. They include:

The hierarchy diagram above includes a Limousine class and a MovingVan class, but we have not defined those classes yet.

In the Problem 1 section of your ps4_partI document (see above), answer the following questions:

  1. (1 point) Which of the classes that are shown in the diagram above are a superclass of the TractorTrailer class?

  2. (1 point) If we have a TractorTrailer object that has been assigned to a properly declared variable t, is it possible to make the following call?

    t.getMileage()
    

    Explain briefly why or why not.

  3. Write a definition for the Limousine class that takes full advantage of inheritance.

    A Limousine object should have all of the same state and behavior as an Automobile object. In addition, it should maintain additional state that keeps track of:

    • whether the limousine has a sun roof (true or false)
    • how many bottles of champagne it can chill (a non-negative integer)

    When a Limousine object is printed, we should see its make, its model, and the number of seats available to customers, which is two fewer than the total number of seats. For example, if the Limousine is a Cadillac XTS-L with a total of 8 seats, printing it should produce the following output:

    Cadillac XTS-L (seats up to 6 customers)
    

    Note that the output mentions 6 seats, because only 6 of the 8 seats are available for customers.

    In your ps4_partI file, add a definition of this class that includes the following:

    1. (1 point) a class header that sets up the appropriate inheritance

    2. (2 points) whatever new fields are needed to capture the state of a Limousine object. Make sure that you take inheritance into account when deciding which fields to include.

    3. (2 points) a constructor that takes as parameters the make, model, year, and total number of seats, as well as a boolean value indicating whether the limo has a sun roof and an integer indicating how many bottles of champagne it can chill. The constructor should ensure that the object is not put in an invalid state (throwing an exception as needed), and it should take whatever steps are needed to initialize the object.

    4. (3 points) any necessary methods. It should be possible for a client to obtain the value of any of the fields, and to change the value of any field that can be changed in an Automobile object. However, you should assume that the portion of the state specifying whether there is a sun roof and how many champagne bottles can be chilled will never change, and thus mutator methods are not needed for those fields. You also don’t need to define an equals method for this class.

Problem 2: Inheritance and polymorphism

18 points total; 2 points each part; individual-only

Imagine that you have a set of related classes that have been defined using inheritance. Here are the key facts about these classes:

In addition, you should make the following assumptions:

Answer the following questions in light of the above information about these classes. Before you begin, you may find it helpful to draw an inheritance hierarchy for the classes, although doing so is not required.

  1. (2 points) The information above states that the Zoo class has its own equals() method that overrides the inherited one. Where does the equals() method that Zoo overrides come from? Be as specific as possible, and explain your answer briefly.

  2. (2 points) List all of the fields in a Yoo object – both the ones that it declares and the ones (if any) that it inherits.

  3. (5 points) Consider the following code fragment:

    Yoo y1 = new Yoo();
    System.out.println(y1.one(10));
    System.out.println(y1.two());
    System.out.println(y1.three(12.5));
    System.out.println(y1.equals(y1));
    System.out.println(y1);
    

    Each of the println statements in this code fragment displays the result of a method call. (This includes the fifth println statement, in which the Java interpreter calls a method on our behalf.) However, it is possible that one or more of these methods calls would fail to compile because the necessary method is neither defined in the Yoo class nor inherited from a superclass of Yoo.

    In section 2-3 of ps4_partI, we have included a table that you should complete with appropriate information about each of these method calls. We have filled in the first row for you, and you should complete the remaining rows.

  4. (3 points) Now imagine that you want to add a non-static method to the Too class. It should be called avg(), it should take no parameters, and it should return the average of all of the integer fields in the called Too object. Add a full definition of that method to section 2-4 of your ps4_partI file. Make sure to take into account the fact that the classes employ proper encapsulation. Make the average as precise as possible.

  5. (6 points) For each of the following assignment statements, indicate whether it would be allowed according to the rules of polymorphism, and explain briefly why or why not.

    1.     Woo w = new Too();

    2.     Zoo z = new Woo();

    3.     Zoo z = new Yoo();

    4.     Too t = new Zoo();

Problem 3: Memory management and the ArrayBag class

12 points total; individual-only

In this problem, you will draw a series of memory diagrams that illustrate the execution of a program that operates on objects of the ArrayBag class from lecture.

Consider the following Java program:

public class ArrayBagTest {
    public static void main(String[] args) {
        ArrayBag b1 = new ArrayBag(3);
        ArrayBag b2 = new ArrayBag(3);
        ArrayBag b3 = b2;

        // part 1: what do things look like when we get here?

        // part 2: what do things look like at the start of
        // this method call?
        b1.add("hello");

        b2.add("world");
        b3.add("hello");

        // part 3: what do things look like when we get here?

        System.out.println(b1);
        System.out.println(b2);
        System.out.println(b3);
    }
}
  1. In section 3-1 of ps4_partI, we have given you the beginnings of a memory diagram. On the stack (the region of memory where local variables are stored), we have included a frame for the main method. On the heap (the region of memory where objects are stored), we have included the ArrayBag object to which the variable b1 refers and its items array. As usual, we have used arrows to represent the necessary references.

    Complete the provided memory diagram so that it shows what things look like in memory just before the call b1.add("hello").

    To do so, you should:

    • Click on the diagram and then click the Edit link that appears below the diagram.

    • Make whatever changes are needed to the diagram. Below the thick horizontal line, we have given you a set of extra components that you can use as needed by dragging them above the thick line and putting them in the correct position. These components include String objects representing the strings "hello" and "world". You may not need all of the provided components.

    • You can also edit any of the values in a field or array by clicking on the corresponding cell and editing the text that is inside the cell.

    • Once you have made all of the necessary changes, click the Save & Close button.

  2. In section 3-2 of ps4_partI, we have given you the beginnings of a memory diagram that you should complete to show what things look like in memory at the start of the execution of b1.add("hello")—just before the first statement of that method is executed.

    Note: To save time, it should be possible to select and copy some of the components of your diagram for 3-1 and paste them into your diagram for 3-2.

  3. In section 3-3 of ps4_partI, we have given you the beginnings of a memory diagram that you should complete to show what things look like in memory after all of the calls to add have returned—just before the print statements execute in main().

    Note: We have included a method frame for add, but it may or not be needed in this diagram; you should delete it if you determine that it would no longer be present in memory.

  4. What would be printed by this program? You may find it helpful to consult the toString method of the ArrayBag class.

Submitting your work for Part I

Note: There are separate instructions at the end of Part II that you should use when submitting your work for that part of the assignment.

Submit your ps4_partI.pdf file using these steps:

  1. If you still need to create a PDF file, open your ps4_partI file on Google Drive, choose File->Download->PDF document, and save the PDF file in your ps4 folder.

  2. Login to Gradescope by clicking the link in the left-hand navigation bar, and click on the box for CS 112.

  3. Click on the name of the assignment (PS 4: Part I) in the list of assignments on Gradescope. You should see a pop-up window labeled Submit Assignment. (If you don’t see it, click the Submit or Resubmit button at the bottom of the page.)

  4. Choose the Submit PDF option, and then click the Select PDF button and find the PDF file that you created. Then click the Upload PDF button.

  5. You should see a question outline along with thumbnails of the pages from your uploaded PDF. For each question in the outline:

    • Click the title of the question.
    • Click the page(s) on which your work for that question can be found.

    As you do so, click on the magnifying glass icon for each page and doublecheck that the pages that you see contain the work that you want us to grade.

  6. Once you have assigned pages to all of the questions in the question outline, click the Submit button in the lower-right corner of the window. You should see a box saying that your submission was successful.

Important

  • It is your responsibility to ensure that the correct version of every file is on Gradescope before the final deadline. We will not accept any file after the submission window for a given assignment has closed, so please check your submissions carefully using the steps outlined above.

  • If you are unable to access Gradescope and there is enough time to do so, wait an hour or two and then try again. If you are unable to submit and it is close to the deadline, email your homework before the deadline to cs112-staff@cs.bu.edu


Part II

60 points total

Important

Don’t forget that each of your methods should be preceded by a comment that explains what your method does and what its inputs are. In addition, you should include a comment at the top of each Java file, and you should use good programming style more generally.

In addition, you should continue to follow the other guidelines that we gave you in the prior problem sets. In particular, see the section labeled Important guidelines that is available here. You also should not use any methods from the Arrays class as part of the methods that your write, as indicated in the guidelines found here.

Problem 4: Implementing the game of CardMatch

30 points; pair-optional

This is the only problem of the assignment that you may complete with a partner. See the rules for working with a partner on pair-optional problems for details about how this type of collaboration must be structured.

Overview

In Problem Set 3, you implemented a Card class for cards that have a color and a numeric value. In this problem, you will use that class as part of game called CardMatch.

In the game of CardMatch, cards have a color (blue, green, red, or yellow) and a value between 0 and 9. At the start of the game, each player is dealt a hand of five cards, and a single card is turned over to form the beginning of a discard pile.

Players take turns attempting to discard a single card from their hands. In order to discard a card, the card must match either the color or the value of the card at the top of the discard pile. For example, if the card at the top of the discard pile is a green 5, a player could play either a green card of any value or a 5 card of any color. If a player has no cards that match the top of the discard pile, they must draw a card and wait until their next turn.

The game continues until a player has no cards left or until a player has 10 cards in their hand. At the end of the game, the player whose final hand has the smallest total value wins the game and earns the total value of the other players’ final hands. To reduce the likelihood of a player winning with 10 cards, a penalty of 20 points is added to the value of any hand with 10 cards. If there are two or more players whose hands are tied the same smallest final value, no one wins any points.

For example, let’s say that there are two players and one of them accumulates 10 cards, ending the game. Assume that the final hands of the players are:

player 1: red 2, yellow 5, blue 1
player 2: green 3, red 1, blue 2, red 2, yellow 1, yellow 3, red 1, blue 0, green 1, red 5

Player 1 ends up with the final hand with the smallest total value (2+5+1 = 8) and thus wins the game. Player 2’s final hand value is 3+1+2+2+1+3+1+0+1+5 = 19, plus the added 20-point penalty, to give 39. Player 1 earns 39 points.

Because the player with the smallest total value wins, players have an incentive to discard cards with a high value.

Sample runs

The version of the game that you will implement will allow a human player to play against the computer. Here are some sample runs of the game:

Notes about the sample runs:

Getting started

  1. If you haven’t already done so, create a folder named ps4 for your work on this assignment. You can find instructions for doing so here.

  2. Put a copy of your Card.java file from Problem Set 3 in your ps4 folder. Note: If you are working with a partner and you both have your own version of the Card class, you should pick one of them to use for this assignment.

  3. Download the following files:

    Make sure to put both of these files in your ps4 folder, along with your Card.java file. If your browser doesn’t allow you to specify where a file should be saved, try right-clicking on its link above and choosing Save as... or Save link as..., which should produce a dialog box that allows you to choose the correct folder for the file.

  4. In VS Code, select the File->Open Folder or File->Open menu option, and use the resulting dialog box to find and open the folder that you created for this assignment. (Note: You must open the folder; it is not sufficient to simply open the file.)

    The name of the folder should appear in the Explorer pane on the left-hand side of the VS Code window, along with the names of the files.

Task 1: review the provided code

In the Explorer Pane, click on the name CardMatch.java, which will open an editor window for that file.

This class contains the main method of the program; you will run this class to start the program. In addition, this class serves as a blueprint for objects that maintain the state of a CardMatch game. It includes fields for things like the deck, the players, and the card at the top of the discard pile, and it includes methods that are used to execute the various stages of the game. You should not make any modifications to this class except for the single change specified in Task 3.

Begin by reading over the code that we have given you. In particular, you should look at how the CardMatch class will make use of the types of objects that you will create below.

You do not need to fully understand how the Deck class works, but we encourage you to look it over. It is a fully implemented class that serves as a blueprint for objects that represent a deck of CardMatch cards. Deck objects have several non-static methods, the most useful of which are the shuffle and dealCard methods. It uses a random-number generator when shuffling the cards to get a different ordering of the deck each time. When testing your code, it’s possible to control the numbers generated by the random-number generator so that you can get repeatable hands of cards. See the section below entitled Testing your code for more details. You should not modify the code in this class.

Task 2: create a blueprint class for a player

Write a class named Player that serves as a blueprint for objects that represent a single CardMatch player. Make sure to save it in your ps4 folder.

Import the java.util package at the start of the file.

Each Player object should have the following components:

  1. three fields:

    • one called name to keep track of the player’s name (a single string)
    • one called hand for an array to hold the cards in the player’s hand
    • one called numCards to keep track of how many cards are currently in the player’s hand Make sure that your field definitions prevent direct access by code from outside the class.
  2. a constructor that takes a single parameter for the name of the player. It should initialize all of the fields. Among other things, it should create the array that will store the cards. Make the collection big enough to store the maximum number of cards in a given hand (10). Use the class constant CardMatch.MAX_CARDS to specify this value, rather than hard-coding the integer 10.

  3. an accessor named getName that returns the player’s name.

  4. an accessor named getNumCards that returns the current number of cards in the player’s hand.

  5. a toString method that just returns the player’s name.

  6. a mutator named addCard that takes a Card object as a parameter and adds the specified card to the player’s hand, filling the array from left to right. It should throw an IllegalArgumentException if the parameter is null, or if the player already has the maximum number of cards.

  7. an accessor named getCard that takes an integer index as a parameter and returns the Card at the specified position in the player’s hand, without actually removing the card from the hand. For example, if p is a Player, p.getCard(0) should return the card at position 0 in p‘s hand – i.e., the first/leftmost card. If the specified index does not correspond to one of the cards in the hand, the method should throw an IllegalArgumentException.

  8. an accessor method named getHandValue that computes and returns the total value of the player’s current hand – i.e., the sum of the values of the individual cards, plus an additional 20-point penalty if the hand has the maximum number of cards. Use the class constants given in CardMatch.java for the maximum number of cards and for the penalty associated with having that many cards.

  9. an accessor method named displayHand that prints the current contents of the player’s hand, preceded by a heading that includes the player’s name. Each card should be printed on a separate line, preceded by the index of its position in the hand. For example:

    John's hand:
      0: red 7
      1: green 2
      2: blue 3
    

    See the sample runs for additional examples. Note that the spacing matters. In particular, there should be:

    • exactly two spaces before each index value
    • no space between an index and its colon
    • exactly one space after each colon
    • exactly one space between each card’s color and value
    • no spaces at the end of any line.
  10. a mutator method named removeCard that takes an integer index as a parameter and both removes and returns the Card at that position of the player’s hand. If the specified index does not correspond to one of the cards in the hand, the method should throw an IndexOutOfBoundsException.

    If the card being removed is not the rightmost card in the hand, the rightmost card must be moved into the position of the card that is being removed. For example, if the hand is currently the four cards {blue 3, red 2, yellow 7, green 1} and you are removing the card at position 1 (the red 2), you must replace it with the last card (the green 1), and thus the resulting hand would be: {blue 3, green 1, yellow 7}.

  11. an accessor method named getPlay that determines and returns the number corresponding to the player’s next play: either -1 if the player wants to draw a card, or the number/index of the card that the player wants to discard from his/her hand. The method should take two parameters: a Scanner object that can be used to read from the console, and a Card object representing the card that is currently at the top of the discard pile.

    • The method should print the appropriate prompt (see the sample runs) and read an integer from the console. If the number entered is invalid (i.e., if it is neither -1 nor an index of one of the cards in the hand), the method should continue asking for a new value until the player enters a valid one.

    • You do not need to worry about whether the specified card matches the top of the discard pile, because the code that we have given you in the CardMatch class already checks for that.

    • You may assume that the player never enters a non-integer.

    • Because this version of the method is for a human player, it can ignore the second parameter (the card at the top of the discard pile). The version of this method that you will write in Task 3 will be for a computer user, and it will use the second parameter.

After completing all of Task 2, you should be able to run the CardMatch class, and run it to play the game.

When running the program, you should highlight CardMatch.java in the list of files before using F5 to run the program. Another option is to right-click on the name of the file in the Explorer pane and choose Run or Run Java.

At this point, the computer will be represented by a Player object, which means that you will be able to see the contents of its hand, and that its plays will be determined using the getPlay method that you implemented above. In other words, you will need to enter the plays for both players!

If VS Code reports problems in the CardMatch class, that probably means that there are problems in the headers of one or more of your Player methods. Change your Player class as needed until the CardMatch class compiles and runs. Remember that you are not allowed to change the Deck class in any way. In addition, you should not change the CardMatch class at this point in the process.

Task 3: create a blueprint class for a computer player

The Player class that you wrote for Task 3 serves as a blueprint for the human player — since its getPlay method asks the user of the program to enter the next play from the console. In this task, you will write a class named ComputerPlayer that serves as a blueprint for objects that represent a computer player.

Save it in the same folder as your other classes for this program. Import the java.util package at the start of the file.

Most of the state and behavior needed for a ComputerPlayer is already present in Player. Thus, you should make ComputerPlayer a subclass of Player, so that it will inherit the fields and methods of that class. In addition to the inherited fields and methods, this class will need:

  1. its own constructor, which should take the name of the player as a parameter and call the constructor of the superclass to do the actual work of initializing the inherited fields.

  2. a displayHand method that overrides the inherited version of that method. This version of the method should simply print the number of cards in the ComputerPlayer‘s hand. For example:

    the computer's hand:
      3 cards
    
    • Use the name given to the player when the object was created (which may not always be "the computer").
    • If there is only one card, use the word "card" instead of "cards".
  3. a getPlay method that overrides the inherited version of that method. This version of the method should figure out if the computer has a card that matches the card at the top of the discard pile (this card is passed in as the second parameter of the method). If the computer doesn’t have a matching card, the method should return -1 so that the computer will end up drawing a card. If the computer does have one or more matching cards, the method should return the index of the card that should be played.

    • For full credit, this method should take into account the values and/or colors of the cards when choosing between two or more matching cards. Simply choosing the matching card with the highest value will earn full credit.

    • Optionally, you could also factor in the color of the cards. For example, if the computer has several different cards that match the value of the card at the top of the discard pile, it might make sense for it to choose the one with the color that is shared by the largest number of other cards in the computer’s hand.

Once you have defined your ComputerPlayer class, modify the line of code in the CardMatch constructor that assigns a value to the second element of the players array (players[1]). Instead of assigning a Player object, it should now assign a ComputerPlayer object. You should not make any other changes to the CardMatch class.

If you have implemented everything correctly, the computer’s hand should now be hidden when you run the program, and the computer should determine its own play, rather than asking you to enter it from the keyboard.

Once all of these tasks are completed, you should have a working CardMatch game!

Testing your code

To get repeatable hands for testing purposes, you can specify a seed for the random-number generator used by the Deck class when it shuffles the deck. Here is one way to do so:

  1. As needed, open the folder containing your code by using the File->Open Folder or File->Open menu option in VS Code.

  2. If you don’t already have a Terminal pane at the bottom of the VS Code window, use the Terminal->New Terminal menu option to open one.

  3. Enter the following command from the Terminal to compile your code:

    javac CardMatch.java
    

    If executing this command produces error messages describing bugs in your code, fix them, save the file(s) in VS Code, and try again. Repeat this process until your code compiles without any error messages.

  4. Enter the following command from the Terminal to run your code with a random seed:

    java CardMatch seed
    

    where you replace seed with an integer.

Other testing notes

Problem 5: Adding methods to the ArrayBag class

30 points total; individual-only

Begin by downloading the following file:
ArrayBag.java

Make sure to put the file in your ps4 folder.

Open the file in VS Code, and you will see the ArrayBag class from lecture.

Add the methods described below to the ArrayBag class, and then add code to the main() method to test these methods. You should not add any new fields to the class.

  1. public int roomLeft()

    This method should return the number of additional items that the called ArrayBag has room to store. For example, the following test code:

    ArrayBag b1 = new ArrayBag(10);
    System.out.println("room before: " + b1.roomLeft());
    b1.add("hello");
    b1.add("world");
    System.out.println("room after: " + b1.roomLeft());
    

    should output:

    room before: 10
    room after: 8
    

    Hint: This method should only need one or two lines of code.

  2. public boolean isFull()

    This method should return true if the called ArrayBag is full, and false otherwise. For example, the following test code:

    ArrayBag b1 = new ArrayBag(2);
    System.out.println(b1.isFull());
    b1.add("hello");
    System.out.println(b1.isFull());
    b1.add("world");
    System.out.println(b1.isFull());
    

    should output:

    false
    false
    true
    
  3. public void increaseCapacity(int increment)

    This method should increase the maximum capacity of the called ArrayBag by the specified amount. For example, if b has a maximum capacity of 10, then b.increaseCapacity(5) should give b a maximum capacity of 15. As part of your implementation, you will need to create a new array with room to support the new maximum capacity, copy any existing items into that array, and replace the original array with the new one by storing its reference in the called object.

    For example, the following test code:

    ArrayBag b1 = new ArrayBag(10);
    b1.add("hello");
    b1.add("world");
    System.out.println(b1);
    System.out.println("room before: " + b1.roomLeft());
    
    b1.increaseCapacity(5);
    System.out.println(b1);
    System.out.println("room after: " + b1.roomLeft());
    

    should produce the following output:

    {hello, world}
    room before: 8
    {hello, world}
    room after: 13
    

    Special cases:

    • If increment is 0, the method should just return.
    • If increment is negative, the method should throw an IllegalArgumentException.
  4. public boolean removeItems(ArrayBag other)

    This method should attempt to remove from the called ArrayBag all occurrences of the items found in the parameter other. If the called object contains multiple copies of an item from other, all of the copies should be removed. The method should return true if one or more items are removed, and false otherwise. For full credit, you should take full advantage of the existing ArrayBag methods.

    For example, consider this test code:

    ArrayBag b1 = new ArrayBag(6);
    String[] words1 = {"hello", "you", "how", "are", "you", "today?"};
    for (String w : words1) {
        b1.add(w);
    }        
    System.out.println(b1);
    
    ArrayBag b2 = new ArrayBag(6);
    String[] words2 = {"not", "bad", "how", "are", "you", "doing"};
    for (String w : words2) {
        b2.add(w);
    }        
    System.out.println(b2);
    
    System.out.println(b1.removeItems(b2));
    System.out.println(b1);
    System.out.println(b2);
    

    Running it should display the following:

    {hello, you, how, are, you, today?}
    {not, bad, how, are, you, doing}
    true
    {hello, today?}
    {not, bad, how, are, you, doing}
    

    Special cases:

    • If the parameter is null, the method should throw an IllegalArgumentException.

    • If the parameter is an empty ArrayBag, the method should return false.

  5. public ArrayBag intersectionWith(ArrayBag other)

    This method should create and return an ArrayBag containing one occurrence of any item that is found in both the called object and the parameter other. For full credit, the resulting bag should not include any duplicates. For example, if b1 represents the bag {2, 2, 3, 5, 7, 7, 7, 8} and b2 represents the bag {2, 3, 4, 5, 5, 6, 7}, then b1.intersectionWith(b2) should return an ArrayBag representing the bag {2, 3, 5, 7}. Give the new ArrayBag a maximum size that is equal to the number of items in the bag with the smaller number of items (but see below for an exception). The order of the items in the returned ArrayBag does not matter.

    Special cases:

    • If there are no items that occur in both bags—including cases in which one or both of the bags are empty—the method should return an empty ArrayBag.

    • If the parameter is null, the method should throw an IllegalArgumentException.

    • In general, the returned ArrayBag should have a maximum size that is equal to the number of items in the bag with the smaller number of items. However, because it’s not possible to construct an ArrayBag with a maximum size of 0, you should give the new ArrayBag a maximum size of 1 if one or both of the original bags are empty.

    For full credit, you should take full advantage of the existing ArrayBag methods. They will make your job much easier!

    For example, running this test code:

    ArrayBag b1 = new ArrayBag(10);
    String[] letters1 = {"a", "a", "b", "d", "f", "f", "f", "g"};
    for (String ltr: letters1) {
        b1.add(ltr);
    }
    System.out.println(b1);
    
    ArrayBag b2 = new ArrayBag(8);
    String[] letters2 = {"a", "b", "c", "d", "d", "e", "f"};
    for (String ltr: letters2) {
        b2.add(ltr);
    }
    System.out.println(b2);
    
    ArrayBag b3 = b1.intersectionWith(b2);
    System.out.println(b3);
    System.out.println(b3.numItems());
    System.out.println(b3.roomLeft());
    System.out.println(b1);   // make sure original bags are unchanged
    System.out.println(b2);
    

    should output:

    {a, a, b, d, f, f, f, g}
    {a, b, c, d, d, e, f}
    {a, b, d, f}
    4
    3
    {a, a, b, d, f, f, f, g}
    {a, b, c, d, d, e, f}
    

    Note: The items in the intersection ({a, b, d, f}) can appear in any order.

Submitting your work for Part II

Note: There are separate instructions at the end of Part I that you should use when submitting your work for that part of the assignment.

You should submit only the following files:

You do not need to resubmit your Card.java. We will use our version of that class when testing your code.

Make sure that you do not try to submit a .class file or a file with a ~ character at the end of its name.

Here are the steps:

  1. Login to Gradescope as needed by clicking the link in the left-hand navigation bar, and then click on the box for CS 112.

  2. Click on the name of the assignment (PS 4: Part II) in the list of assignments. You should see a pop-up window with a box labeled DRAG & DROP. (If you don’t see it, click the Submit or Resubmit button at the bottom of the page.)

  3. Add your files to the box labeled DRAG & DROP. You can either drag and drop the files from their folder into the box, or you can click on the box itself and browse for the files.

  4. Click the Upload button.

  5. You should see a box saying that your submission was successful. Click the (x) button to close that box.

  6. The Autograder will perform some tests on your files. Once it is done, check the results to ensure that the tests were passed. If one or more of the tests did not pass, the name of that test will be in red, and there should be a message describing the failure. Based on those messages, make any necessary changes. Feel free to ask a staff member for help.

    Note: You will not see a complete Autograder score when you submit. That is because additional tests for at least some of the problems will be run later, after the final deadline for the submission has passed. For such problems, it is important to realize that passing all of the initial tests does not necessarily mean that you will ultimately get full credit on the problem. You should always run your own tests to convince yourself that the logic of your solutions is correct.

  7. If needed, use the Resubmit button at the bottom of the page to resubmit your work. Important: Every time that you make a submission, you should submit all of the files for that Gradescope assignment, even if some of them have not changed since your last submission.

  8. Near the top of the page, click on the box labeled Code. Then click on the name of each file to view its contents. Check to make sure that the files contain the code that you want us to grade.

Important

  • It is your responsibility to ensure that the correct version of every file is on Gradescope before the final deadline. We will not accept any file after the submission window for a given assignment has closed, so please check your submissions carefully using the steps outlined above.

  • If you are unable to access Gradescope and there is enough time to do so, wait an hour or two and then try again. If you are unable to submit and it is close to the deadline, email your homework before the deadline to cs112-staff@cs.bu.edu