CompSci.rocks
FRQcsapa

DiverseArray: 2015 FRQ 1

A step-by-step solution to the 2015 AP CSA FRQ 1 (DiverseArray), covering summing a one-dimensional array, computing two-dimensional array row sums, and detecting duplicate sums in Java.

Three related methods about summing and comparing arrays make up this AP Computer Science A free-response question — starting with a single one-dimensional sum, then building up to comparing sums across every row of a two-dimensional array.

What This FRQ Tests

  • AP CSA units: Unit 6 (Array), Unit 8 (2D Array), and Unit 4 (Iteration)
  • Core skill: looping over a one-dimensional array to accumulate a total, then reusing that same logic across every row of a two-dimensional array
  • Secondary skill: comparing values pairwise across a collection to detect duplicates
  • Official category: this year's FRQ 1 is entirely array-based rather than "Methods and Control Structures." Pre-2019 AP CSA exams didn't follow today's fixed FRQ-number-to-category order (that pattern wasn't standardized until the 2019-2020 Course and Exam Description redesign), so this one is best described as testing Array (Unit 6) and 2D Array (Unit 8) content directly, regardless of which numbered slot it happens to occupy.

The Setup

  • A DiverseArray class (not shown) holds three static methods, all working together
  • arraySum(int[] arr) — returns the sum of every entry in a one-dimensional array
  • rowSums(int[][] arr2D) — returns a one-dimensional array holding the sum of each row of a two-dimensional array; arr2D is in row-major order, so arr2D[r][c] is the entry at row r, column c
  • isDiverse(int[][] arr2D) — returns whether every row sum in a two-dimensional array is unique
  • Each part explicitly builds on the one before it: rowSums is required to call arraySum, and isDiverse is required to call rowSums, for full credit

Part (a): Writing arraySum(int[] arr)

Step-by-Step Approach

  1. Start a running total at 0.
  2. Loop over every index of arr.
  3. Add each entry to the running total.
  4. Return the total once the loop finishes.

The Code

public static int arraySum(int[] arr)
{
    int sum = 0;

    for (int i = 0; i < arr.length; i++)
    {
        sum += arr[i];
    }

    return sum;
}

Why Each Piece Matters

  • sum starts at 0 before the loop runs — a running total that begins at the wrong value throws off every entry added afterward.
  • arr.length drives the loop bound instead of a hardcoded number, so the method works correctly no matter how large arr is.
  • sum += arr[i] is shorthand for sum = sum + arr[i] — identical behavior, just less to type.

Tracing the Example

Using the question's own array, arr1 = {1, 3, 2, 7, 3}:

Index Value Running total
0 1 1
1 3 4
2 2 6
3 7 13
4 3 16

Final returned value: 16 — matches arraySum(arr1) exactly as given.

Common Mistakes to Avoid

  • Starting sum at 1 instead of 0. A seemingly small typo that throws off every result by exactly 1.
  • Using <= instead of < in the loop condition. i <= arr.length accesses arr[arr.length], which is out of bounds and throws an ArrayIndexOutOfBoundsException.
  • Forgetting the return statement, or returning sum from inside the loop after only the first iteration.

Part (b): Writing rowSums(int[][] arr2D)

Step-by-Step Approach

  1. Create a new int[] sized to arr2D.length — one slot per row.
  2. Loop over every row index r.
  3. Each row, arr2D[r], is itself a complete one-dimensional array — hand it directly to arraySum.
  4. Store the value arraySum returns at index r of the result array.
  5. Return the filled array once every row has been processed.

The Code

public static int[] rowSums(int[][] arr2D)
{
    int[] sums = new int[arr2D.length];

    for (int r = 0; r < arr2D.length; r++)
    {
        sums[r] = arraySum(arr2D[r]);
    }

    return sums;
}

Why Each Piece Matters

  • arr2D[r] by itself is a full one-dimensional array — exactly what arraySum expects as its parameter. No separate inner loop is needed here at all.
  • Reusing arraySum isn't just a style choice — the question explicitly states "you must use arraySum appropriately to receive full credit." Writing a fresh nested loop that recomputes the same sums would not earn full marks even if the output were correct.
  • sums[r] and arr2D[r] use the same index variable r — the sum computed from row r of the input always lands at position r of the output.

Tracing the Example

Using the question's own mat1:

Row Entries arraySum result
0 1, 3, 2, 7, 3 16
1 10, 10, 4, 6, 2 32
2 5, 3, 5, 9, 6 28
3 7, 6, 4, 2, 1 20

Final returned array: {16, 32, 28, 20} — matches rowSums(mat1) exactly as given.

Common Mistakes to Avoid

  • Writing a brand-new nested loop instead of calling arraySum. Even if the sums come out right, this loses the credit tied to reusing the given method.
  • Sizing the result array by column count instead of row countrowSums returns one entry per row, so the result array's length should match arr2D.length, not the length of an individual row.
  • Using a different index for the result than for the row being summedsums[r] must always correspond to arr2D[r], not arr2D[r - 1] or arr2D[r + 1].

Part (c): Writing isDiverse(int[][] arr2D)

Step-by-Step Approach

  1. Get every row's sum at once by calling rowSums(arr2D).
  2. Compare every pair of sums to each other.
  3. If any two match, the array isn't diverse — return false immediately.
  4. If no pair ever matches after checking everything, return true.

The Code

public static boolean isDiverse(int[][] arr2D)
{
    int[] sums = rowSums(arr2D);

    for (int i = 0; i < sums.length; i++)
    {
        for (int j = i + 1; j < sums.length; j++)
        {
            if (sums[i] == sums[j])
            {
                return false;
            }
        }
    }

    return true;
}

Why Each Piece Matters

  • Calling rowSums(arr2D) first is required by the question ("you must use rowSums appropriately"), and it also means the sums only ever get computed once, not recomputed for every comparison.
  • The inner loop starts at j = i + 1, not 0. Starting at 0 would compare sums[i] to itself (always equal, which would incorrectly report every array as non-diverse) and would also re-check every pair a second time in the opposite order.
  • Returning false immediately the moment a match is found avoids unnecessary comparisons once the answer is already known.

Tracing the Example

Using the question's own two arrays:

  • mat1 has row sums {16, 32, 28, 20} — every pair is checked (16 vs 32, 16 vs 28, 16 vs 20, 32 vs 28, 32 vs 20, 28 vs 20) and none match, so the loop finishes and isDiverse(mat1) returns true.
  • mat2 has row sums {14, 35, 36, 14} — the very first row (index 0, sum 14) and the last row (index 3, sum 14) match, so isDiverse(mat2) returns false as soon as that pair is reached.

Both results match the question exactly.

Common Mistakes to Avoid

  • Recomputing sums manually instead of calling rowSums — again, the question specifically requires using the given method.
  • Starting the inner loop at j = 0 instead of j = i + 1, which compares every sum to itself and breaks the whole method.
  • Returning true from inside the loop as soon as one comparison doesn't match, instead of only returning true after every pair has been checked with no matches found.

Key Takeaways

  • When a problem hands you multiple related methods and says to "use" an earlier one, that's not just a suggestion — it's graded, and reimplementing the same logic instead of calling the given method can cost credit even when the output is correct.
  • A row of a two-dimensional array, arr2D[r], is itself a complete one-dimensional array — passing it directly into a method built for one-dimensional arrays is often the cleanest way to share code across dimensions.
  • Detecting duplicates in a list of values is a classic double-loop pattern: compare every element to every element that comes after it (starting the inner loop at i + 1, not 0) so no pair is skipped or double-checked.

Related FRQs