Sound FRQ Solution

The first free response question on the 2011 AP Computer Science exam had students work with an array of integers. The values in the array were describing the volume of a sound file. The higher the value, the higher the amplitude.

I liked this one because it didn’t seem as arbitrary as some of the free response questions. It’s close to code that someone might write to solve a real world problem.

Sound.java

Let’s start by looking at the Sound.java file that holds the two methods you’ll be implementing. I’m stripping out the comments so we can focus on the code part. But it’s probably worth your time to take a look at the full problem.

public class Sound {
    private int[] samples;

    public int limitAmplitude(int limit) {
        // Part A
    }

    public void trimSilenceFromBeginning() {
        // Part B
    }
}

The important part here, aside from the methods that we’re going to be implementing, is the samples instance variable. We’ll need to use that in our solutions.

limitAmplitude

For part A we’re implementing a method called limitAmplitude that goes through the samples instance variable and sets all values that are above or below limit to that limit.

That part should be relatively easy. Hopefully by the time you’re working on this problem you’ve gone through a bunch of labs working with primitive arrays. What tends to get missed through is that this method also has to return the number of replacements that are made. When we’ve done this as a lab in class it’s returning the value that misses the most points.

public int limitAmplitude(int limit) {
    int cnt = 0; 
    for (int i=0; i<samples.length; i++) {
        if (samples[i] > limit) {
            samples[i] = limit;
            cnt++;
        }
        else if (samples[i] < -limit) {
            samples[i] = -limit;
            cnt++;
        }
    }
    return cnt; 
}

What I did was create a variable called cnt that holds the number of replacements. Then the code loops through samples and compares every value to limit. If the value is greater than limit that position is set to limit and cnt is incremented. Same goes when the value is less than negative limit.

trimSilenceFromBeginning

Again, we’re working with the primitive array samples. This time though we’re removing “silence” from the beginning of the array. We’re removing any leading zeros from samples.

First, we need to know the size of the new array. For that, we need to count leading zeros. And I did that with a while loop. Normally I would probably abstract out this little piece into a separate method, but you don’t want to do that on the AP exam.

Next the new array gets sized.

We copy everything except the leading zeros from samples into ray.

And last we set samples = ray to update the instance variable.

public void trimSilenceFromBeginning() {
   int x = 0;
   while (samples[x] == 0) {
      x++; 
   }
   int[] ray = new int[samples.length - x];
   for (int j=0; j<ray.length; j++) {
      ray[j] = samples[j + x];
   }
   samples = ray; 
}

Because the preconditions told us that there would be at least one non-zero value, the first loop can just look for zeros. Otherwise we would have to keep track of where we are in samples as to not go out of bounds.

The most common mistake I’ve seen on this problem is students not reading the problem and removing all zeros from samples and not just leading zeros.

This site contains affiliate links. If you click an affiliate link and make a purchase we may get a small commission. It doesn't affect the price you pay, but it is something we must disclose.