The Sound problem from the 2011 AP Computer Science Exam is typical of free response problems that test arrays. The problem requires you to find and modify elements that exceed a given limit.

Review the Sound free response problem with AP CS Tutor Brandon Horn.

## Sound Part (a): limitAmplitude

``` public int limitAmplitude(int limit)
{
int numChanges = 0;

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

return numChanges;
}
```

## Sound Part (b): trimSilenceFromBeginning

```public void trimSilenceFromBeginning()
{

// precondition guarantees at least 1 non-zero element
// so no need to check for out of bounds

for(int i = leadingZeros; i < samples.length; i++)

}
``` ## 6 thoughts on “Sound free response answer”

1. Mr. Zurla

it appears that your array “withoutzeros” will have length 8 for the example array “samples” as given in question 1b when it should have length 12. might want to rework your loops

• Brandon Horn

I should have followed my own advice and read the problem carefully. My original solution removed all zeros in the array, not just leading zeros. I’ve updated the post to reflect a correct solution. Thanks for the report.

2. Taylor

This seems like an easier solution

```int count = 0;
int loopControlVar = 0;
boolean silence = 0;
int [] newSamples = new int[loopControlVar - leadingZeros];
for(int temp : samples)
{
if(temp==0 && silence == true)
{
loopControlVar++;
}
else
{
silence = false;
newSamples[count] = temp;
count++;
}
}
```
• Brandon Horn

Your proposed solution incorrectly declares the length of `newSamples` to be 0. Modifying the values of `loopControlVar` and `leadingZeros` within the loop does not retroactively alter the length of the array.

It is necessary to determine the number of leading zeros before initializing the new array. This requires 2 traversals of the array (one traversal is partial).

• Taylor

I see what you mean.

This would work right?

```int count = 0;
boolean silence = true;

for(int temp : samples)
{
if (temp == 0 && silence == true)
{
}
else
{
silence = false;
}
}

int [] newSamples = int [samples.length - leadingZeros];
silence = true;

for(int temp : samples)
{
if(temp == 0 && silence == true)
{

}
else
{
silence = false;
newSamples[count] = temp;
count++;
}
}
```

Dang. That is really is much more complicated than your solution though.

Thank you

• Brandon Horn

Is the goal of this solution to replace the call to `arraycopy` with a second loop? A regular `for` loop would work better than a foreach loop since you need the index.

```for(int i = 0; i < newSamples.length; i++)
Your approach to tracking silence using the variable `silence` isn't wrong but it is unnecessary. The first loop in my solution tracks silence without the extra variable. Your use of `silence` in your second loop is also unnecessary. `leadingZeros` is sufficient to identify the offset of the first non-zero value from the beginning of the array.
• `silence == true` is a silly comparison. `silence` is already a `boolean`.
• `temp` is a poor name for your loop variable because it doesn't identify its purpose. `value` would be better since it suggests a value in the array.
• The `if` statement in your second loop is blank and has an `else` statement. Check the opposite instead.