TIM GALLAGHER: Hey, everybody.
Welcome back to AP Daily, the practice sessions for 2023
for AP Computer Science A. My name is
Tim Gallagher, from Winter Springs High School,
located just outside of beautiful Orlando, Florida.
ROB SCHULTZ: And my name is Rob Schultz, from Bellbrook High
School in Bellbrook, Ohio.
Welcome back, everybody.
This is video number 7 in the series.
And today, we're going to focus on 2D arrays.
That's free response question 4.
Let's go ahead and take a look at the question.
So this is question 4 from the 2022 exam.
This is the data question.
Just reading through what the question's walking us through,
it says, this question involves a two-dimensional array
of integers that represents a collection of randomly
generated data.
And it gives us a partial declaration
of the data class below.
So we're going to end up writing two methods of the data class.
Now, we've talked in past videos,
the first thing we want to do as we're
looking at our free response question,
is we want to make note of our instance variables.
So we have two instance variables.
We've got public static final int MAX,
which it's going to have a value,
but we don't really need to know that specific value.
The value could change.
The other thing I want to point out
is that it's a little odd to see an instance variable that's
public.
But in this case, our instance variable's
final, which means it's not going to change.
So that's OK that it's public.
The other thing that we have is we
have a private reference variable to an int 2D array.
And it's called grid.
So make sure that as we work with our 2D array,
we're using grid.
If we get to the point that we need this maximum value,
make sure we're using max.
So, as we've said in the past, put a big star
beside our instance variables so that we know we're using.
It's not going to be myGrid or theGrid,
maximum, things like that.
Make sure we're using the instance variables exactly
as they're written, OK?
So for part A, we're going to write a public method called
repopulate.
And this one says it fills all the elements of grid
with randomly generated values.
Notice our precondition.
Grid is not null.
It has at least one element.
So remember, preconditions are guaranteed to be true.
We don't have to test for those.
We're also going to write a method called
countIncreasingCols, or count increasing columns.
And the purpose of this one is to return
the number of columns in grid that are in increasing order.
That's going to be our part B. And Tim is
going to walk us through that in just a minute or two, OK?
We should also point out there may be some instance variables,
constructors, methods, things like that that aren't shown.
But really, we're focused on the things
that we have the information about.
So we don't really need to worry about other things that
might or might not be there.
OK, you ready to take a look at part A?
Part A says we're going to write the repopulate method, which
assigns a newly generated random value to each element of grid.
Now, we have specific criteria we have to meet.
Every value has to meet all of the following criteria.
Our value has to be between 1 and MAX.
So there's that reference to that public final instance
variable MAX.
Every value that we calculate has to be divisible by 10.
Or I should say, every value we compute
has to be divisible by 10.
But the catch is, it can't be divisible by 100.
So we've got some checking we need
to do as we work through here.
The other thing we have to keep in mind
is that all of our valid values have
to have an equal chance of being generated.
So we have to be careful about how we're using math.random
to make sure that every value has an equal shot of being
generated.
All right, so here's our repopulate method.
This is the point where I want you to pause the video,
take a little time, and work out a solution.
Again, be aware of your time.
Be aware of the time that you have on the actual exam.
And try and see if you can come close to that amount of time
for part A and part B. But go ahead and pause.
And when you're ready to come back and go through part A,
press play, and we'll go through it together.
OK, welcome back, everybody.
So let's take a look at a solution.
So, here's our canonical solution.
And as we've said on past videos,
the canonical is just a solution.
It's not the only solution.
And here are the point values for part
A. OK, let's see how we did.
So, part one says we traverse grid with no bounds there.
So as we look, notice that because we're
traversing a 2D array, we need nested for loops.
We need something that's going to control rows and columns.
The other thing to make note of is that when we look at rows,
we're looking at the length of grid.
But when we look at the number of columns,
we're looking at the length of the first row of grid.
So our row equals 0.
We're going to check grid bracket 0 to get the length.
That's actually going to give us the number of columns.
And we want to make sure we don't go out
of bounds on either of the rows or the columns.
And then we do access every element.
So we are traversing the grid, no bounds there.
So, part one looks good.
Number two, do we generate a random integer
in a range based on MAX?
Now, notice it doesn't say anything
about making sure we use MAX correctly.
It just says we generate a random integer
in a range based on MAX.
So we are.
We're calling math.random times MAX.
That, in and of itself, is enough to get us the point.
But we are calling it correctly.
We're casting as an int, and then we're
adding 1 to make sure that we're getting the right values
that we're looking for.
Number three-- do we ensure that all produced values are
divisible by 10 but not by 100?
Well, we do.
We have a while loop that's going
to repeat if we get a value that's not divisible by 10
or we get a value that is divisible by 100,
because those are the things we don't want.
So if, by some chance, we get a value that's
not divisible by 10 or it is divisible by 100,
we're going to regenerate a new value
and we're going to continue to regenerate values
until we get something that breaks us out of that while
loop, meaning we get the thing that we're looking for.
All right, and then finally, do we assign appropriate values
to all the elements of grid?
This is our algorithm point.
And to be honest, the algorithm is pretty much
the entire method.
I mean, pretty much all of this is included.
We assign appropriate values to all of the elements of grid.
Well, we need our for loops to do that.
We need our check to make sure that we're
getting correct values, that we get appropriate values.
And we have to assign them to grid row column as we go.
So this whole thing, making sure that everything
is in the right spot and that it correctly
does what it's supposed to do, that's our algorithm point.
Tim, I'm going to pass things over to you for part B.
TIM GALLAGHER: All right, thanks, Rob.
Here we go with part B. So, part B
says we are going to write the countIncreasingCols method.
And this is going to return the number of columns
in the grid that are in increasing order.
So a column is considered increasing if, it says,
if the elements in each row after the first row
is greater or equal to the elements of the previous row.
And a column with only one row is, of course,
going to be considered an increasing order.
So here are some examples to show
how the countIncreasingCols method works,
and the return values for possible contents of grid.
So in this first one, let's say I've got this 3 by 3 grid.
Which of the columns--
remember, the columns are the ones that go up and down.
Which of the columns are increasing
from the top of the grid down to the bottom
of the grid in each column?
Well, if you'll notice, only one of them, that first column,
is in increasing order, the 10, 20, 30.
So the return value for this example
would be 1 because the first column is in increasing order,
the second and third columns are not in increasing order.
In this example here, the return value for this grid would be 2.
Why?
Because two of the columns, the first column
right here in column 0 and also the column with 440 and 440,
would also be considered increasing
because they're equal.
Remember, increasing is when the values in each subsequent row
is either the same or greater.
So in this case, we would return 2
because we have two columns that are in increasing order.
Make sense?
So let's go ahead and look at writing this method.
So the countIncreasingCols method
is going to return an integer.
It's going to return the number of columns in grid
that are in increasing order.
Of course, with the precondition like Rob had mentioned before,
we want to make sure we look at those.
But we don't have to test for them.
We know the grid is not going to be null.
We know the grid is going to have
at least one element in it.
So, great time to go ahead and hit pause and see
if you can take this 2D array and count
the number of increasing columns we have.
Go ahead and hit pause.
We'll come right back to you.
OK?
Here we go.
Let's see how you did.
So, let's look at a canonical solution.
So in this case, we're going to notice a few things.
Again, this is a solution.
It's a canonical one, but yours might be slightly different.
But there's a few key things to point out.
Notice I have nested for loops, just like Rob had in part A.
But in here, I have to ensure that I'm
going to do what's called a column major order traversal.
So notice the first for loop is going
to loop through the columns, and the second
or the inner for loop is going to loop through the rows.
So for every column, I'm going to look
at each row element in each column
as I traverse through all the columns-- a column major order
traversal.
And then also notice where I'm looking
at consecutive elements.
You see row column and grid row minus 1 column.
You can do row plus 1, row minus 1,
depending on how you set up for loops to make sure
that you stay in balance.
So let's go ahead, and you'll notice that we count.
I'll talk about how this algorithm works a little bit
more as we look into the points.
So here's the points for part B, points 5
through 9 of our 9-point question.
The first one says, do we traverse
the grid in column major order without any loop header bounds
errors?
So making sure that for loops themselves
don't go out of bounds-- notice again, as I mentioned,
it is a column major traversal.
And I do access grid row col somewhere inside
of the nested for loops.
Then, we want to make sure that we compare
two elements in the same column of the grid,
whether it's grid row column compared
to grid row minus 1 column, like we have here,
or it could be plus 1.
Again, depending on how you're looking at the loop.
We just want to make sure that we're
comparing different members of the same column.
So the row numbers are different.
The column numbers are the same.
That would earn you point 6.
Now, did you determine whether a single column
is in increasing order?
So, when you look at that comparison--
notice how I look at grid row column--
make sure that's less than the one before it.
You might have said, is grid row column
greater than the one after it?
Here, we're doing less than the one before it
and making sure that this entire algorithm is good.
Now, notice how we're doing the algorithm.
We've got a Boolean up there called
ordered, set it equal to true.
If I ever find an instance when I'm going through the column
that one row is not less than the row before it,
meaning if I'm not an increasing order,
I automatically set ordered to false.
After my for loop is done.
I'm now going to evaluate that ordered.
And that's going to determine whether or not
I found a column that is in increasing order,
or it's not in increasing order.
So the next point is going to be,
have I now counted all the columns
that I've identified as increasing order?
And that's where this if statement comes in.
If ordered is still true--
so, if ordered-- count plus plus.
So I found a column that is in increasing order.
Notice my ordered-- if it's still true,
that means I never found something to throw it off.
It only takes one to set ordered equal to false.
And as long as ordered is still true,
I'm going to do a count plus plus.
And that's the entire algorithm making sure
that I count all the columns that are in increasing order.
Finally, am I returning the calculated count
of increasing columns?
Not just any number, but the number
that I determined based on my algorithm
that that is going to be the correct number of columns
that are an increasing order.
All right, so, thank you very much for joining us.
Remember, that concludes all of our free response questions.
We have one more practice session left.
We're going to do some multiple choice
questions over the next one.
But for more practice, again, on free response questions,
check out AP Central and AP Classroom as well.
You can download a whole bunch of free response questions.
Practicing those will put you in just a fantastic position
to do absolutely awesome on the AP Computer Science
A exam coming up very soon.
Again, for Rob Schultz and myself,
thank you for joining us.
We'll see you next time.
Take care.