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.
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.
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
, 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.