Data Free Response Solution

The Data free response question on the 2022 AP Computer Science exam has you working with a matrix and random numbers, implementing two methods that are given to you as part of a class shell named Data.

You can, and probably should, view the entire question on the College Board Website so that you have the entire problem statement in front of you.

Class Shell

The following, along with comments explaining what you needed to implement was given to you.

public class Data {
    public static final int MAX = /* value not given */;
    private int[][] grid;

    public void repopulate() {
        // Part A
    }

    public int countIncreasingCols() {
        // Part B
    }
}

We need to get a couple pieces of information out of what we’re given here.

First, there is a constant named MAX that we’ll be referencing later. They intentionally didn’t give MAX a value. Best guess is they wanted to make sure that you’re using MAX and not some arbitrary number. If they had set it to a value like 5, certainly there would be students using 5 instead of MAX.

Next is that there’s an instance variable named grid that’s a 2 dimensional array made of primitive int values. We don’t see a constructor, or anywhere that grid is initialized so we’ll assume that that’s done somewhere for us. In fact, the problem does state that grid is not null and has at least one element.

Part A - repopulate

The repopulate method is supposed to fill the grid with random numbers between 0 and MAX (inclusive), but also that is divisible by 10, but not divisible by 100. So we’ll need to use Math.random(), but also a loop to make sure that we’re getting values that match the requirements.

We also need a set of nested loops to go through each element in the array.

for (int row = 0; row < grid.length; row++) {
    for (int col = 0; col < grid[row].length; col++) {
        int rnd = (int)(Math.random() * MAX) + 1;
        while (rnd % 10 != 0 || rnd % 100 == 0) {
            rnd = (int)(Math.random() * MAX) + 1;
        }
        grid[row][col] = rnd;
    }
}

We’ve got a nested loop going through each row and column. Inside the loop a random int is generated and the run through a loop to make sure it matches the requirements. If it does, the while loop never iterates. If it doesn’t, the while loop keeps iterating until we find a match.

It’s not included in the AP Java Subset, but we could also use a do-while loop to here and I think it makes it a little shorter. If you haven’t come across a do-while loop before, it’s similar to a while loop except the condition is checked at the end of the loop instead of the beginning. What this means is that while a while loop can iterate 0 times, a do-while loop will always iterate at least once.

for (int row = 0; row < grid.length; row++) {
    for (int col = 0; col < grid[row].length; col++) {
        do {
            grid[r][c] = (int)(Math.random() * MAX) + 1;
        } while (grid[r][c] % 10 != 0 || grid[r][c] % 100 == 0);
    }
}

The first time the do-while loops it puts a random value in the array. At the end it checks that value, and if it’s not valid it keeps looping until it is.

Part B - countIncreasingCols

Part B, countIncreasingCols, wants you to go through a matrix and count how many of the columns are in increasing order.

Let’s look at an example.

In this matrix, the first column (10-20-30) is in increasing order, but the second and third are not. So the method should return 1.

We need to do two things. First, go through each column and check if it’s in increasing order. Along the way we need to keep track of whether each column is increasing and if it is, count it so we return the right value.

public int countIncreasingCols() {
    int cnt = 0;
    for (int c=0; c<grid[0].length; c++) { 
        bool inc = true;
        for (int r=0; r<grid.length - 1; r++) {
            if (grid[r][c] > grid[r+1][c]) {
                inc = false;
            }
        }
        if (inc) {
            cnt++;
        }
    }
    return cnt; 
}

This one feels weird because we’re looping through the columns first, but that’s what we need to do for this to work.

On the first line there’s a variable cnt declared that will hold the number of increasing columns we find. At the end that value is returned.

Next is the outer loop. This is looping through each column. We’re using grid[0].length because we know that, since it’s an AP exam, each row will have the same number of columns. That’s not always true, but College Board doesn’t use ragged arrays in their questions.

Inside the outer loop we have a variable inc that’s a boolean. We’re going to use this to keep track of whether the column is increasing or not. We set it to true at the beginning of the loop. I found it easier to assume that every column is increasing until we find otherwise than the other way around.

Next is the inner loop. This is looping through each row in the column. We’re using grid.length - 1 because we’re comparing the current row to the next row. If we didn’t subtract 1, we’d get an ArrayIndexOutOfBoundsException because we’d be trying to access a row that doesn’t exist.

Inside the inner loop we’re checking if the current row is greater than or equal to the next row. If it is, we set inc to false. If this were not an AP exam question I would have added a break; statement immediately following inc = false; to break out of the loop, but break is not part of the AP Java Subset so I didn’t include it above.

After the inner loop is done, we check if inc is true. If it is, we increment cnt by 1.

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.