We have to use a nested loop. That is a loop inside a loop.
If we have a 2dArray SCORES[6][5] it means that we have 6 rows and 5 columns. So the total number of elements will be 30. Usually in this cases the rows are the students and the columns the scores. So we have 6 students with 5 scores each.
Output all the scores from the students. We have another array with names[6] where the name of the student is.
(This is similar to page 7 in advance book)
The output will be something like this
Print the grades that are better than a 5 and who got them.
The output will be something like this
Print the grades that are better than a 5 and who got them and which exam was it (exams go from 1 to 5)
Print the average of the grades of each student.
Output the average of the exams
Another example with students. We have an array of 30 students which names are stored in the linear array NAMES[]. They have done 6 exams and their grades are with percentage (So they go from 0 to 100). We want to print who did better in each exam (we can consider no ties).
The grades of the exams are stored in a 2D array called SCORES[30][6]
Other example
We're EXO manager (the group) and we have to divide the payment (this is fiction) to each person in the group using the time that they are singing in each Concert. They are very similar but they want to be precise.
The tour was called EXODUS and had 44 concerts. (that's kind of a lot)
The income that they have to split is saved in the array CONCERTINCOMES[44] that is splited in the different concerts.
The time that they have singed each singer in the performance is saved in a 2D array SINGINGTIME [9][44], being 9 the performers and 44 the concerts.
Create a code that calculates what is the total of each performer of EXO.
for each concert we need to make the splits between the 9
then we are going to add them.
finally we output
In this case we need to define a new array and then output the elements of the array.
We're a bank and our top directives have to declare expenses in their travels. We're using a 2D array to track this, being the rows the different executive and the columns the different months of the year. Expenses are in Euros.
This array looks like this
expenses[6][12] = {{130, 1500, 230 , 0, 0, 0, 2030, 120, 23, 0, 0, 0}{1500, 0,0,0, 200, 300,150, …} …}
Construct algorithms that find things and output them. Each sentence is an algorithm.
For this we only need to add all of the expenses
For this we are going to find out the expenses of each month and compare the to a maximum. We need also to store the index of the maximum because that's the month name
Here we need to loop for each month and compare if their current sum is bigger than the others. Is like a case or finding "MAX_INDEX" but with 2D arrays.
About the CURRENT_SUM
CURRENT_SUM is set and re-set inside the loop of months because is not a cummulative sume but each month needs a different sum, so we store it separately. If we write this:
In this case the MOST_MONTH will be always the last because in the second month CURRENT_SUM will be the sum of all the expenses of the MONTH and the previous one.
So as a rule of thumb, if we have to reset for each loop, the VARIABLE=0 goes inside. If it doesn't goes outside.
:::
Find out what is the average of spending of the most spending directive.
First we have to find the most spending directive. Then output it's average. We can do it by parts and we can store averages and/or sums or not.
A solution without any new arrays
Solution with a new array:
Another notation with filling a new 1D array
Credit: Z.A.
We need to loop through each directive and have a counter with each month that is exactly 0
Credit T.J.
2D arrays behave like 2D matrixes in math. We're not working on that (in IB they don't do matrixes even in HL AA) but we can be familiar with some names
The main diagonal is the conjuct of elements that go with the first row, first column, second row second element and so on:
Using the typical notation for looping through a
Check if some 2D array is valid or not. Usually we have to check item by item by some condition (or several conditions!)
Another option (a bit more tedious) is to count the valid elements. If all of them are valid, the total array is valid. Remember that the total number of elements
Sometimes we need to loop through the array in no order but some other times we actually need to traverse the array in the correct order.
Let's define a simple 2D array of 3x4 as an example. Let's call it MAT
indexes | [0] | [1] | [2] | [3] |
---|---|---|---|---|
[0] | 3 | 4 | 8 | 9 |
[1] | 100 | 46 | 12 | 7 |
[2] | 0 | 90 | 1 | 22 |
If we want output from left to right and then top to botton then we need to loop through the rows and then through the columns. Let's say that we want to just output it. It would be like this
The output will be: 3,4,8,9,100,46,12,7,0,90,1,22
But if we want output first columns also written as from top to botton and then left to right we need to inverse these loops.
The output will be: 3,100,0, 4, 46, 90,8,12, 1, 9, 7, 22
We can go even further and go backwards going rom the bottom right to the top left, first rows, then columns. To do it we need to reverse the loop
In some info I have seen the keyword "downward to " written in the for loop that is also correct.
The output will be in this case:
22,1,90,0,7,12,46,100,9,8,4,3
You can always trace the algorithm with the values of ROW and COL to get the info. In the last case we would have a value that is 2,3 then 2,2 and so on.
From this 3x3 MAT
indexes | [0] | [1] | [2] |
---|---|---|---|
[0] | 1 | 2 | 3 |
[1] | 4 | 5 | 6 |
[2] | 7 | 8 | 9 |
We want to output the elements in this order
7,4,1,8,5,2,9,6,3
Solution on the spoiler:
Then we want to from right to left then top to bottom
Solution on the spoiler:
Sometimes we need to fill other linear arrays with one 2D array. For doing that we need to have those arrays initialized and with suficient size to have storage of what we want to fill in.
Then what we usually need to do is to know what are conditions to fill the array or arrays (we might have more than one). And also be aware of the index of the array that we are filling in
For my experience in the real world you call it "fill" the arrays but in IB exams I have seen "construct" or create as the verb to declare and fill the arrays with values
Let's start simple
If we have this array (MATHEW):
indexes | [0] | [1] | [2] | [3] |
---|---|---|---|---|
[0] | 3 | 4 | 8 | 9 |
[1] | 100 | 46 | 12 | 7 |
[2] | 0 | 90 | 1 | 22 |
We can store in array the ODD elements in the array ODD
For doing this the could would be like this:
In exam questions I have seen that the array where we have to store the values is given but we need to create the variable to store the index.
Now let's supose that we have to store not only the odds but also the even numbers in the array EVEN.
Construct the code for creating the 2 arrays (ODD and EVEN) from the 2D Array MATHEW.
We have 2 arrays with two independent indexes!
Solution on the spoiler section
credit to Y.C.
Another solution with 2 loops (longer but correct also)
credit to V.G.
Let's have a 2D array of numbers, for example 6 by 6
Find the average of numbers.
Why div and not "/" if it's what we see in regular programming?
Slash is equivocous. It can be correct but with div we're making sure that we're talking about the integer division. So I suggest to use div.
The diagonals are a concept in 2D arrays (and matrixes)
They don't ask it directly but they expect you to handle this concept.
When we have a square matrix (same size in both dimensions) we can find the 2 diagonals. The main diagonal includes the elements with the indexes [0][0], [1][1], [2][2], … [n-2][n-2], [n-1][n-1] where n is the size of the array (and the array size in total is )
The other (secondary) diagonal starts with [0][n-1], [1][n-2], [2][n-3], … [n-2][1], [n-1][0].
Why is it useful. For example in saving distances between stations (each index corresponds to a specific station). The elements in the main diagonal are the ones that corresponds to the distance between a station and itself and it would be always 0.
Here you would have the duplicated 2D array
indexes | [0] | [1] | [2] | [3] | [4] | [5] |
---|---|---|---|---|---|---|
[0] | 0 | 4 | 7 | 2 | 1 | 8 |
[1] | 4 | 0 | 8 | 9 | 1 | 5 |
[2] | 7 | 8 | 0 | 2 | 4 | 3 |
[3] | 2 | 9 | 2 | 0 | 10 | 2 |
[4] | 1 | 1 | 4 | 10 | 0 | 11 |
[5] | 8 | 5 | 3 | 2 | 11 | 0 |
Also since, usually, the distance is the same between A and B and between B and A, we don't have to write all the values in this matrix. We can write in one of the halves and leave the other empty. This is done to avoid having duplicate data that leads to inconsistencies.
indexes | [0] | [1] | [2] | [3] | [4] | [5] |
---|---|---|---|---|---|---|
[0] | 0 | 0 | 0 | 0 | 0 | 0 |
[1] | 4 | 0 | 0 | 0 | 0 | 0 |
[2] | 7 | 8 | 0 | 0 | 0 | 0 |
[3] | 2 | 9 | 2 | 0 | 0 | 0 |
[4] | 1 | 1 | 4 | 10 | 0 | 0 |
[5] | 8 | 5 | 3 | 2 | 11 | 0 |
With that information, let's go back to Numbers[6][6]
Credit V.G.
The tricky part here is the 5-X. Remember that the secondary diagonal goes [0][n-1], [1][n-2] and so on.
In this case having it with the same variable that changes over time ensures that we're only adding the elements of that diagonal.
Remember that this is going to sum all the elemnents!
This is a common mistake
This was an exercise of a past exam. It's unlikely that it's going to happen again but having it in mind is useful for other cases.
A magic square is a square that their rows, their columns and their diagonals have the same sum. So to check it out you will need to have a flag variable and find if all the sums are equal.
Construct the code
When we create a 2D array it's usually empty and then we need to fill it with data. One way to do it is just by rows or by columns. The most basic way to do this would be something like this is to fill it with consecutive numbers from 1 to NxM (being NxM the size of the dimensions of the array)
This would be the example for a MATTHEW of 3x4
indexes | [0] | [1] | [2] | [3] |
---|---|---|---|---|
[0] | 1 | 2 | 3 | 4 |
[1] | 5 | 6 | 7 | 8 |
[2] | 9 | 10 | 11 | 12 |
The code would be the following:
Other example that I've seen in some exams is to trace an algorithm that, for example, fills a 2D array.
Take this example
They told as also that A
is a 2D array and they ask you to trace the algorithm to show the contents of the array A after the algorithm is executed for N = 3
Solutions on the spoiler
Trace table
N | K | ROW | COL | A[ROW][COL] |
---|---|---|---|---|
3 | 9 | 2 | 0 | 9 |
3 | 8 | 2 | 1 | 8 |
3 | 7 | 2 | 2 | 7 |
3 | 6 | 1 | 0 | 6 |
3 | 5 | 1 | 1 | 5 |
3 | 4 | 1 | 2 | 4 |
3 | 3 | 0 | 0 | 3 |
3 | 2 | 0 | 1 | 2 |
3 | 1 | 0 | 2 | 1 |
This leads to an array A that has this content:
indexes | [0] | [1] | [2] |
---|---|---|---|
[0] | 3 | 2 | 1 |
[1] | 6 | 5 | 4 |
[2] | 9 | 8 | 7 |
Exercise:
Fill the array A for N = 4
Solution after the spoiler
credit A.P.
Credit A.B.
In the last exercise we saw one way to fill an array but what happen if we want to fill it in weird ways?
Imagine that we want to do fill Matthew in a way that always the numbers that are consecutive they have a consecutive number nearby. We can do a snake.
Something like this:
indexes | [0] | [1] | [2] | [3] |
---|---|---|---|---|
[0] | 1 | 2 | 3 | 4 |
[1] | 8 | 7 | 6 | 5 |
[2] | 9 | 10 | 11 | 12 |
So in this case we're going to go from left to right in the first row and from right to left in the second row and back left to right in the third and so on.
In some exams they tell the idea of this code and then you need to actually write it. For example the description for this will be
Remember. If they tell you the initialization of a variable it means the first value it gets.
Construct the code described above
Another posible solution without ifs nuances
Small execise: find the problem of this algorithm (is not a syntax error)
solution on the spoiler (a whole class of HL struggled with this)
If we have an odd number of rows we're going to be out of boundaries. In this case we're going to have ROW equal to N
One possible solution is this
Another solution that can fill the array but doesn't follow the instructions given would be starting by 12 and fill backwards.
Something that can be asked in an exam is
Hint: in this question they don't ask for the values, they ask for the indexes the numbers that go after PETER in PETER[0][3].
Also notice than PETER doesn't have the same size of MATTHEW
Solution in the spoiler
The fist element of the bottom rowe that will be the [3][5] and the last the [3][0]
Sometimes we find 2D arrays that represents data with fields. For example if we have an array called CLIENTS
and each row respresents a client and each column represents a specific data.
indexes | [0] | [1] | [2] | [3] |
---|---|---|---|---|
[0] | Pepito | Perez | Mataró | 08304 |
[1] | Juanita | López | Barcelona | 08003 |
[2] | Ivan | Jokovich | Madrid | 28040 |
In this case the column [0] represents names, column [1] represents surnames, column [2] represents cities and column [3] represent postal codes.
Imagine that in this array instead of having 3 rows we have 256 rows.
Construct a code for counting how many clients live in Madrid and display the result. You have access to the 2D array CLIENTS
Remember that in this cases we need to understand what is the size of the array (remember that sometimes the size of the array is not a number but a variable like N
). In this case we have 256 rows and 4 colums so the size of the array is 256x4.
In this case we don't need to loop through all the elements but only through all the rows. To do that we write
Since we need to count and output the count we can also add it.
To identify the element that we need to check is allways in the same column. If we check again we can see that that column is [2] so we only need to check if the [2] element of the row is "Madrid". To access it we use CLIENTS[ROW][2]
Lastly inside the if we only need to add 1 to the counter that we're going to output later.
Exercises:
Count how many clients come from Paris. And output the number.
Solution by the students on the spoiler
credit M.S.
Output if we have any client that is called Rocco. We need to have a different message if we have and if we have not.
Solution by the students on the spoiler
credit M.S.
credit K.B.
Output if we have any client that is called Rocco and lives in Paris. We need to have a different message if we have and if we have not.
Solution by the students on the spoiler
credit M.S.
credit K.B.
Sometimes we can find an auxiliary 1D array to a 2D array as a header for example if we have a 2D array that tells the distances between train stations
This is the 2D array DISTANCES
indexes | [0] | [1] | [2] | [3] |
---|---|---|---|---|
[0] | 0 | 0 | 0 | 0 |
[1] | 10 | 0 | 0 | 0 |
[2] | 15 | 50 | 0 | 0 |
[3] | 35 | 40 | 25 | 0 |
And then you have the array STATIONS that follows this structure
indexes | [0] | [1] | [2] | [3] |
---|---|---|---|---|
values | Concepcion | Lota | Chillan | Los Angeles |
Construct a code that finds the maximum distance between Stations and outputs the distance and the stations that are more far apart.
Solution from one student in the spoilers:
credit A.B.
Statement
Construct an algorithm in pseudocode that inputs the names of two bus stations and outputs the distance between them. If any of the inputted names are not found, the method should output an appropriate message. The name of the subprogram is findDistance
Working
After the spoiler
In this case first we need to understand that we have 2 inputs that are strings that should be in the array STATIONS and we need to know the index of them in order to find the distance.
The "signature" of this method in this case should be something like findDistance(STATION1, STATION2)
.
So we have something like this right now
we can work with other names for the STATION1 and STATION2 and also we can finish with "end method" instead of end findDistance
The next thing that we need to do is to know is the inputs (STATION1
and STATION2
) are valid.
To do that we need to loop through the array, which one? STATIONS
Inside that loop we're going to check if we have the value of STATION1 or STATION2 in 2 different ifs.
What do we do in those ifs? Store the index. In this case I'm going to use those indexes as a flag variable and I'm going to initialize them as -1. If we have found the STATIONS the indes should be a number from 0 to 3 (cannot be -1 because there is no -1 index) so I can use an if to see if there is no problem with that.
Now we have to check if we have updated the indexes, to do it we need to compare those indexes. We can either check if both of them are between 0 and 3 or check if they are still -1. The former indicates that we have change both of them. The later checks if any of those indexes did not update at all.
This goes after the loop through STATIONS.
In the case that we have found that either one or the other index is -1, there is no need to continue with the execution. We can stop it through a return (return always stops the method) or using an else to execute the rest of the code.
Now we have to check what are the indexes relatively from each other. In this case we have to because the information of the distance is in the lower diagonal (where ROW > COL)
So we need an if
If INDEX1 is equal than INDEX2 the distance is 0 because is the same station.
If INDEX1 is bigger than INDEX2 we need to check DISTANCES[INDEX1][INDEX2] to find the distance
If INDEX2 is bigger than INDEX1 we need to swap and check DISTANCES[INDEX2][INDEX1] to find the distance.
To write it down it would look like this:
Why the change between Index2 and index1? Because we are making sure that we have access to the element that has information.
:::
Result
After the spoiler
This is an exercise of filling a 2D array now in a spiral way. The idea is that we create a way spiral the creation.
We have a NxM 2D array
We need to fill it in an spiral from left to right then top to bottom, right to left and finally bottom to top.
To do that first we need to define the name of the array and the NxM
Then, we need to do a loop. That loop would need to last until we finish the filling. We can tell because the number of VALUE that will be increasing will achive up to the value of
Now we need to know what are the boundaries that we're going to loop through.
Those boundaries can be described as TOPROW, BOTTOMROW, LEFTCOL and RIGHTCOL
The initial values of these are the indexes of those elements (Rows and columns)
Those values are set before the loop since we're not going to reset them.
The first loop will go from left to right in the top row. So we can write it like this
inside we need to set the value into the array (SPIRAL) and increment value by 1.
we set this in the while:
Not to repeat the values we need to add the +1 to TOPROW
Now we need to loop through the right column like this
And we add it as before.
We add the substract 1 to RIGHTCOL not to overwrite the value…
We continue doing like this. The solution afther the spoiler
credit Z.A.
Let's have a 2DArray called MAT
Construc in pseudocode a sub-program that accepsts a 2D array MAT and finds if the main diagonal has a bigger sum than the secondary diagonal and outputs the conclusion. If that information cannot be found, an appropiate message should be displayed.
Solution in the spoiler:
Solution 1
Credit C.V. (with modifications)
Credit K.B.