Solution: Adding a Ball

Adding a ball to the bag is the same as adding a value to the dynamic array. A bag makes no promise about order, so we can put the new ball anywhere there is room. Putting it in the next free slot costs the least, so that is where we put it.

Solution

The solution is the same as DynamicArray.add, except we write a BallColor instead of an int:

public void add(BallColor ball) {
  if (size == balls.length) {
    grow();              // out of room — make the backing array bigger first
  }
  balls[size] = ball;    // drop the ball in the next free slot
  size++;                // one more ball is now in the bag
}

Note that size here means the same thing it meant for DynamicArray. It is the number of slots that hold real balls, and the slots from size onward are allocated but empty.

Here is a trace on a fresh bag. The diagrams use a bag with capacity 4 instead of capacity 10, just so they fit on the page. The logic is identical.

A fresh bag starts empty: size is 0 and every slot is free, so size points at the first slot.

┌─────┬─────┬─────┬─────┐
│  _  │  _  │  _  │  _  │
└─────┴─────┴─────┴─────┘
   ↑
  size

add(BLACK) drops a black ball in the next free slot (the one size points at) and increases size to 1.

┌───────┬───────┬───────┬───────┐
│ BLACK │   _   │   _   │   _   │
└───────┴───────┴───────┴───────┘
            ↑
          size

add(BLUE) drops a blue ball in the next free slot and increases size to 2.

┌───────┬────────┬───────┬───────┐
│ BLACK │  BLUE  │   _   │   _   │
└───────┴────────┴───────┴───────┘
                     ↑
                    size

A second add(BLACK) drops another black ball in the next free slot and increases size to 3. A bag allows duplicates, so a repeated color is no problem.

┌───────┬────────┬───────┬───────┐
│ BLACK │  BLUE  │ BLACK │   _   │
└───────┴────────┴───────┴───────┘
                             ↑
                            size