CS 261 Assignment #4

Due Friday, March 10th by 11:59pm
5% late if submitted by 3/18
10% late if submitted by 3/19
(Not accepted after 3/19)

Teams

You are required to work in pairs on this assignment. (Team assignments are below.) Do not start writing any code until you've met with your partner and discussed the assignment and possible approaches. As on the lab, please be kind in your interactions with your partners! Keep in mind that students in this class have a range of previous programming experience, and that some have been college students for longer than others. We're all in this together, and you have something to learn from your partner, no matter who they are or what their previous experiences have been. Ideally, your team would work together using the same pair programming approach as used on the lab, but however you choose to complete the assignment, I will assume that each member of the team has contributed equally to the project. If that assumption isn't true, please contact me privately. Please respect the privacy and scheduling preferences of your partner when finding times to work! Don't ask for a phone number if your partner isn't comfortable sharing it. When setting up times to work, it's probably best to aim for spaces where folks will be comfortable meeting with relative strangers (e.g. the library), or to work virtually as we do in lab. Please be professional in your conduct!
Spencer Racca-Gwozdzik and Gabriel Guinn
Rohan Crossland and Ethan Spence
Jacob Endrina and Lucas Calaff
Mackenzie Leibee and Noah Sprenger
Noah McCullough and Stephen Rice
Ella Slattery and Jinwoo Choi
Bonacic Bonacic and Alex Lopez
Grey Roppolo and Devan Meyer
Brendan Bell and Cian Monaghan
Brett Garon and Noah Zimmer
Asa Bonner and Liam Bradley and Lucas Takiff

Introduction

On this assignment you'll work individually on a problem I borrowed from LeetCode, a site that programmers use to practice their problem-solving skills on the kinds of problems that might occur during whiteboard interviews with tech companies. You'll need to use stacks and queues in your solution, so it'll be a good chance to practice our most recent material. (If anyone from LeetCode is watching, I promise that I changed enough of the details that a solution to this assignment won't pass the tests for the original problem.)

The task is to "simulate" the behavior of a group of unusual asteroids that all travel along the same line, and at exactly the same speed. Some of them are moving to the left though, while others are moving to the right. You're given a queue of integers representing a row of asteroids where the sign specifies which way they're moving (negative values are moving to the left, and positive values are moving to the right), and the magnitude (the absolute value of the integer) tells you how big the asteroid is. If asteroids collide, the result is a new asteroid that's the sum of the two input values. If a 5 collides with a -3 for example, the result would be 2 — a smaller asteroid that's still travelling to the right. (If the sum is zero, the two asteroids wipe each other out and there's nothing left.)

You need to write a program that takes a queue of integers as input and returns a queue of values describing the state of the system after all collisions have occurred. Below are some sample inputs and outputs to give you a better sense of how the process should work. (The values are shown with [ ]'s but they really are queues.)

Input Output Explanation
[5, -3] [2] The two collide, leaving one asteroid
[4, 5, -3] [4, 2] The 5 hits -3, but result doesn't collide with the 4
[5, -5] [ ] The two wipe each other out
[-2, 5, -3, -1] [-2, 1] The -2 goes left, the 5 hits both -3 and -1
[2, 8, -1, 10, -2, 6, -4, -7] [2, 7, 3] It's complicated...

Approach

We considered a couple of examples to help motivate stacks. For example, when matching parenthesis we used the stack as a kind of "memory" to keep track of unmatched left parens. Once we found their match we removed them from the stack. In our expression evaluator, we once again used the stack as a kind of memory. Since we encountered numbers before the operator that was applied to them, we pushed numbers onto the stack for later use once we came across an operator. In both of these cases a stack was the right tool for the job since we only needed the most recent items in "memory". (A right paren matches the topmost left paren on the stack. An operator works on the top two values on the stack.)

When simulating asteroids, we only get collisions if an asteroid is moving to the right (positive) and encounters a later left-moving (negative) asteroid. There's a similar logic here to the problems in the previous paragraph: When we find a right-moving asteroid, we don't yet know who it's going to hit. (It might not even hit another asteroid!) Right-moving asteroids can therefore be pushed onto a stack, and when we encounter a left-moving asteroid we can "collide it" with the asteroid on the top of the stack. It's a little more complicated than matching parenthesis though, since after the collision we could end up with a left-moving asteroid that might cause additional collisions (with asteroids on the stack), or a right-moving asteroid that needs to be pushed back on the stack or, if the the two have the same magnitude, they might obliterate one another completely.

Also, note that we determine "survivors" from left to right, as we process the input queue. (Those are the ones we're sure aren't going to run into anything — either because they're moving to the left and there are no right-moving asteroids to their left, or there are right-moving asteroids present at the end of the collision process that won't ever hit anything.) That means we don't need the full generality of a list to store the results. A queue will work just fine, since we only need to store new survivors at the end of the queue.

The Assignment

  1. I'm not giving you any starter code for this assignment. Create a project in either BlueJ or Eclipse but make sure the class is called Asteroids and that it contains a static method called collide that takes an input queue of Integers and returns a queue of Integers. You'll lose points if those names and types aren't exactly right.
  2. Your code should implement the approach described above, where right-moving asteroids are pushed onto a stack, and later "collided" with left-moving asteroids encountered in the input queue.
  3. For full credit, don't use anything other than stacks and queues in your solution. You're welcome to use additional stacks or queues as part of your solution if you find that useful, but no lists or arrays. When working with stacks, only use the four basic stack operations (push, pop, peek, and empty).

Grading

This assignment will be graded out of a total of 75 points.

Submitting

Before submitting, test your code thoroughly and double check for comments (including @param and @return directives) above each method. When you're convinced it's ready to go, zip up your project folder and submit it via the Canvas submission tool for Assignment #4.


Brad Richards, 2023