Corrections:
Question 9:
When first analyzing this question, I first thought if a dice is 1 to 6, inclusive, it must contain integers 1 through 6. That must mean integers 1, 2, 3, 4, 5, 6, are included (which is 6 numbers). Therefore, options B and D should be out of the equation. I probably misclicked with B as I meant to select A. This means that we are left with options A, C, and E. The reason why I chose A initially is because I didn’t see the word “independent”, and therefore chosing A means that it would only generate 1 random int from the range (0 to 5, because of its index) and not 2 seperate dices.
We are now left with 2 options, C and E. Both answers contain Math.random to generate a double value from 0 to 1. If we were to multiply by 6, we would get a range from 0 to 6. Transforming the value by using int
will change the double value to an int value, and therefore changing the range to 0 to 5.
The reason the answer is not C, but E is because of the range. As mentioned above, the range will be from 0 to 5, granting only a dice that generates numbers from 0 to 5. Adding 2 will make up the range for 1 to 6 since adding 1 (2 times) will shift the dices range from 0-5 to 1-6. Essentially, the answer should be 1 + (int)(Math.random()*6) + 1 + (int)(Math.random()*6)
, but it is shortened to 2 + (int)(Math.random()*6) + (int)(Math.random()*6)
.
Down below I show a simple demonstration of how this works:
System.out.println("Simplified Version");
public class DiceSimulationSimplified {
public static void main(String[] args) {
int die1 = (int)(Math.random() *6) + 1; //using Math.random function, we generate a random number from 1 to 6
int die2 = (int)(Math.random() *6) + 1; //does it again
int sum = die1 + die2; //adding both dies together
System.out.println("The sum of two dice rolls is: " + sum);
}
}
DiceSimulationSimplified.main(null);
System.out.println(" ");
System.out.println("Unsimplified Version");
public class DiceSimulationUnsimplfied {
public static void main(String[] args) {
int sum = 2 + (int)(Math.random() * 6) + (int)(Math.random() * 6);//combining both functions above
System.out.println("The sum of two dice rolls is: " + sum);
}
}
DiceSimulationUnsimplfied.main(null);
Simplified Version
The sum of two dice rolls is: 10
Unsimplified Version
The sum of two dice rolls is: 12
Question 12:
When I first initially solved this problem, I spent roughly 1 minute on it. It should not be that hard as it is a simple boolean expression. I kind of rushed through this problem without giving it enough thought. I did this problem again with the analysis down below.
Here is a breakdown with step by step analysis:
Expression: (x && y) && !(x || y)
Let’s assume x and y are both true
Step 1: (x && y)
- If both x and y are true, (x && y)
should result in the boolean value of true
Step 2: (x || y)
- If both x and y are true, (x || y)
should result in the boolean value of true (even if only one variable is true)
Step 3: !(x || y) - This means that if the expression (x || y) were to be true, then it would become false because of the “NOT” (!) operator. In our case, it would change (x |
y) from becoming true to false |
Step 4: (x && y) && !(x || y) - Combining it all together, we have the expression (x && y), which is true, and !(x |
y), which is false, which would result in (true && false), which equals false. |
This code also relates with DeMorgan’s Law:
With the notation !(x || y)
, DeMorgan’s Law allows us to change that to (!x && !y)
, which means if both x and y were set initially to true, that means both values would turn to false. If both x and y are false, then the expression (!x && !y)
would result in false.
Down below I also show it with code:
System.out.println("Simplified Example:" );
public class BooleanSimplifiedExample {
public static void main(String[] args) {
boolean x = true;
boolean y = true;
boolean result = (x && y) && !(x || y);
System.out.println("Result: " + result);
}
}
BooleanSimplifiedExample.main(null);
System.out.println(" ");
System.out.println("Unsimplified Example: ");
public class BooleanUnsimplifiedExample {
public static void main(String[] args) {
boolean x = true;
boolean y = true;
boolean result1 = (x && y); //Step 1 with the AND boolean expression
boolean result2 = (x || y); //Step 2 with the OR boolean expression
boolean result3 = !(result2); //Step 3 with the NOT boolean expression
boolean result4 = (result1) && (result3); //Step 4 with the AND boolean expression
System.out.println("Step 1: " + result1);
System.out.println("Step 2: " + result2);
System.out.println("Step 3: " + result3);
System.out.println("Step 4: " + result4);
}
}
BooleanUnsimplifiedExample.main(null);
Simplified Example:
Result: false
Unsimplified Example:
Step 1: true
Step 2: true
Step 3: false
Step 4: false
Question 13:
To be honest, when I first looked at the answer I chose, I don’t understand why I chose that. The array I chose grew in increments of 3 for every index. The mystery value is equivalent to three, so I might have been confused with that.
Now further analyzing the code, the answer should be A because if we were to test the first three index:
1st iteration:
k = 1, x = 3 because mystery(3) is called, so numbers[1] = numbers[0] + 3
–> numbers[1] = 17 + 3
, therefore the 1st index in the new array is 20.
2nd iteration:
k = 1 + 3, k = 4
k = 4, x = 3 because mystery(3) is called, so numbers[4] = numbers[3] + 3
–> numbers[4] = 42 + 3
, therefore the 4th index in the new array is 45.
3rd iteration:
k = 4 + 3, k = 7
k = 7, x = 3 because mystery(3) is called, so numbers[7] = numbers[6] + 3
–> numbers[7] = 48 + 3
, therefore the 7th index in the new array is 51.
The other numbers remain unchanged.
Down below is code to show the process as well.
public class MysteryArray {
private int[] numbers;
public MysteryArray(int[] numbers) { //constructor
this.numbers = numbers;
}
public void mystery(int x) { //code from question
for (int k = 1; k < numbers.length; k = k + x) {
numbers[k] = numbers[k - 1] + x;
}
}
public void printNumbers() { //printing the numbers not seperately, displays nicely
for (int number : numbers) {
System.out.print(number + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] initialNumbers = {17, 34, 21, 42, 15, 69, 48, 25, 39};
MysteryArray mysteryArray = new MysteryArray(initialNumbers); //initializing new array, calling constructor
System.out.println("Initial numbers:");
mysteryArray.printNumbers();
mysteryArray.mystery(3);
System.out.println(" ");
System.out.println("Numbers after mystery(3) is called:");
mysteryArray.printNumbers();
}
}
MysteryArray.main(null);
Initial numbers:
17 34 21 42 15 69 48 25 39
Numbers after mystery(3):
17 20 21 42 45 69 48 51 39
Question 22:
From further analysis, I realized that the answer is A, and not D. I redid it the first time and thought it was E, but then I realized the error I made.
How I thought it was D: I did not fully realize that r = 0, meaning that if numbers[0].length was set to the row length, which is 3, that means the outside for loop would iterate 3 times. That would give an error because the there are only two rows in the 2D array. Down below, you can tell that the output goes from 1 to 2, then 4 to 5, because the code segment prints out 3 rows and 2 columns.
public class AnswerChoiceD {
public static void main(String[] args) {
int[][] numbers = {
{1, 2, 3},
{4, 5, 6}
};
try {
for (int r = 0; r < numbers[0].length; r++) {
for (int c = 0; c < numbers.length; c++) {
System.out.print(numbers[r][c]);
}
}
}
catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Caught an ArrayIndexOutOfBoundsException: " + e.getMessage()); //catches the out of bounds error
e.printStackTrace();
}
}
}
AnswerChoiceD.main(null);
1245
Caught an ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
at REPL.$JShell$13E$AnswerChoiceD.main($JShell$13E.java:25)
at REPL.$JShell$20.do_it$($JShell$20.java:17)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at io.github.spencerpark.ijava.execution.IJavaExecutionControl.lambda$execute$1(IJavaExecutionControl.java:95)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
How I thought it was E: As I caught my mistake with D, I looked at E instantly because it swapped the column and rows. However, the reason why this answer is wrong because of the way it prints out. It starts with index 0 for both rows and then prints it out like that chronologically. Therefore, it will print out the value of 142536.
public class AnswerChoiceE {
public static void main(String[] args) {
int[][] numbers = {
{1, 2, 3},
{4, 5, 6}
};
for (int c = 0; c < numbers[0].length; c++) {
for (int r = 0; r < numbers.length; r++) {
System.out.print(numbers[r][c]);
}
}
}
}
AnswerChoiceE.main(null);
142536
The reason why the answer is E is because it uses an enhanced for loop to print out the numbers in each row in order. The outer for loop starts off by going through the first row by printing out the int n
for each row. It does that until there are no more rows that are needed to be printed out.
public class AnswerChoiceA {
public static void main(String[] args) {
int[][] numbers = {
{1, 2, 3},
{4, 5, 6}
};
for (int[] row : numbers) {
for (int n : row) {
System.out.print(n);
}
}
}
}
AnswerChoiceA.main(null);
123456
Question 26:
To be honest I don’t even know how I got this wrong. Did I misclick the answer? There was no point in selecting the option C as String name = "blackboard"
was not modified at all.
This question goes back to my revisions in question 13 because it has the same printing format as the method start()
in the question by using a for loop:
public void printNumbers() { //printing the numbers not seperately, displays nicely
for (int number : numbers) {
System.out.print(number + " ");
}
System.out.println();
}
Down in the example class below, I used the code from the question and showed how it works. Going back to the explanation above, the String name “blackboard” is not passed through the changeIt()
method, and therefore is not changed at all. However, if I were to set the string “word” to “blackboard”, it would return the substring of it locally in the method. However, it would not change if it is called back into the method start()
. Shown down below:
public class Class {
public static void changeIt(int[] arr, int val, String word) {
arr = new int[5];
val = 0;
word = word.substring(0, 5);
System.out.println("Word changed locally: " + word);
for (int k = 0; k < arr.length; k++) {
arr[k] = 0;
}
}
public static void start() {
int[] nums = {1, 2, 3, 4, 5};
int value = 6;
String name = "blackboard";
String word = "blackboard"; //example where the string "blackboard" is passed through the method changeIt()
changeIt(nums, value, name);
for (int k = 0; k < nums.length; k++) {
System.out.print(nums[k] + " ");
}
System.out.print(value + " ");
System.out.print(name);
}
public static void main(String[] args) {
start();
}
}
Class.main(null);
Word changed locally: black
1 2 3 4 5 6 blackboard
Question 30:
This one is very easy as it is only asks for else if conditions. I most likely misclicked because it is very apparent that option 3 mixes the total cost of the boxes. Additionally, it states that numBoxes > 0
so that condition will always be met. Option 1 is wrong because there is no else statement to prevent the next if statement from overriding the previous if statement.
import java.util.Scanner;
public class InkPenPricing {
public static double getCostOptionI(int numBoxes) {
double totalCost = 0.0;
if (numBoxes >= 10) {
totalCost = numBoxes * 1.50;
}
if (numBoxes >= 5) {
totalCost = numBoxes * 3.00;
}
if (numBoxes > 0) {
totalCost = numBoxes * 5.00;
}
return totalCost;
}
public static double getCostOptionII(int numBoxes) {
double totalCost = 0.0;
if (numBoxes >= 10) {
totalCost = numBoxes * 1.50;
}
else if (numBoxes >= 5) {
totalCost = numBoxes * 3.00;
}
else {
totalCost = numBoxes * 5.00;
}
return totalCost;
}
public static double getCostOptionIII(int numBoxes) {
double totalCost = 0.0;
if (numBoxes > 0) {
totalCost = numBoxes * 5.00;
}
else if (numBoxes >= 5) {
totalCost = numBoxes * 3.00;
}
else if (numBoxes >= 10) {
totalCost = numBoxes * 1.50;
}
return totalCost;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the number of boxes: ");
int numBoxes = scanner.nextInt();
System.out.println("Option I: " + getCostOptionI(numBoxes));
System.out.println("Option II: " + getCostOptionII(numBoxes));
System.out.println("Option III: " + getCostOptionIII(numBoxes));
scanner.close();
}
}
InkPenPricing.main(null);
Enter the number of boxes: Option I: 25.0
Option II: 15.0
Option III: 25.0
Question 32:
The variable “theMajor” is a string so a string compare must be done on the current instance of students in the array. They use the “getMajor” method to get the major from the students list.
Note that the “for” statement iterates over “students” and allows for a reference to an object of type “StudentInfo” inside the “for” block code. You can at get the class instance variables for each instance via calls to the methods for the class. Examples:
k.getAge(); k.getMajor();
If the instance of student matches the major passed into “averageAgeInMajor” method the code next gets the age from the current instance of students in the array using the “getAge” method.
The code:
sum += k.getAge();
adds the age into the sum variable. The count is incremented “count++;” to indicate the numbers of students to calculate the average for.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static class StudentInfo {
private String major;
private int age;
public StudentInfo(String major, int age) {
this.major = major;
this.age = age;
}
public String getMajor() {
return major;
}
public int getAge() {
return age;
}
}
public static class StudentProcessor {
private List<StudentInfo> students;
public StudentProcessor(List<StudentInfo> students) {
this.students = students;
}
public double averageAgeInMajor(String theMajor) {
double sum = 0.0;
int count = 0;
for (StudentInfo k : students) {
if (theMajor.equals(k.getMajor())) {
sum += k.getAge();
count++;
}
}
if (count > 0) {
return sum / count;
}
else {
return -1.0;
}
}
}
public static void main(String[] args) {
List<StudentInfo> students = new ArrayList<>();
students.add(new StudentInfo("Computer Science", 20)); //create a list of students
students.add(new StudentInfo("Mathematics", 22));
students.add(new StudentInfo("Physics", 21));
students.add(new StudentInfo("Computer Science", 23));
//creates an instance of the public class containing the averageAgeInMajor method
StudentProcessor studentProcessor = new StudentProcessor(students);
//calculates and prints the average age for Computer Science majors
double averageAge = studentProcessor.averageAgeInMajor("Computer Science");
System.out.println("Average age for Computer Science majors: " + averageAge);
}
}
Main.main(null);
Average age for Computer Science majors: 21.5
Question 33:
For option I, max is initialized to the minimum value from the Integer class. Next, the for loop iterates through the array comparing max to value where value is the current value in the array. The variable max is replaced with value when max is less than value (meaning a new max value is found).
The reason why option II works the code is almost the same as option I but there’s a flag used for the first pass through the for loop code. Since max is initialized to zero the initial “if” check works. the next “else if” would also work. The end result is the same as option I.
For option III, the variable max is initialized with the first value in the array. The “for loop starts at the second number in the array, which is at position 1. The “if” statement compares the max variable and the current instance of arr we are iterating over. the max variable is set to that instance if max is less. The end result is the same as option II and III.
public class MaxFinder {
public static int optionI(int[] arr) {
int max = Integer.MIN_VALUE;
for (int value : arr) {
if (max < value) {
max = value; //setting value = max if the value after is greater than the "max"
}
}
return max;
}
public static int optionII(int[] arr) {
int max = 0;
boolean first = true;
for (int value : arr) {
if (first) {
max = value;
first = false; //setting the boolean expression first to false
}
else if (max < value) {
max = value; //using else if statement to set value = previous max value
}
}
return max;
}
public static int optionIII(int[] arr) {
int max = arr[0];
for (int k = 1; k < arr.length; k++) {
if (max < arr[k]) {
max = arr[k];
}
}
return max;
}
public static void main(String[] args) {
int[] exampleArray = {4, 8, 2, 10, 6};
System.out.println("Max using approach I: " + optionI(exampleArray));
System.out.println("Max using approach II: " + optionII(exampleArray));
System.out.println("Max using approach III: " + optionIII(exampleArray));
}
}
MaxFinder.main(null);
Max using approach I: 10
Max using approach II: 10
Max using approach III: 10
Question 34:
I think I misinterpreted the answer. The reason why the “expression” listOfWords.size() - 1 should not be correct is because listofWords.size() will give you the size of the list. If there are three items in the list then it is set to there. This means that the only possible options are “b” or “d”.
The reason why it is “d” is because listOfWords.size() - 1
accounts for index 0. In the code, since we have 3 indexes, setting k one less than our index will account for all 3 indexes.
Regardless if the “expression” for both “a” or “c” were correct, the corresponding “condition” code for “a” definitely does not work. The first pass k = 0 so the first word would get missed. For option “c” the condition code of “k != sizeOfList - 1” would not work with the length set differently.
import java.util.ArrayList;
import java.util.List;
public class WordsWithCommas {
private List<String> listOfWords;
public WordsWithCommas(List<String> listOfWords) {
this.listOfWords = listOfWords;
}
public String wordsWithCommas() {
StringBuilder result = new StringBuilder("{");
int sizeOfList = listOfWords.size();
for (int k = 0; k < sizeOfList; k++) {
result.append(listOfWords.get(k));
if (k != sizeOfList - 1) {
result.append(", ");
}
}
result.append("}");
return result.toString();
}
public static void main(String[] args) {
List<String> wordsList = new ArrayList<>();
wordsList.add("One");
wordsList.add("Two");
wordsList.add("Three");
WordsWithCommas wordsWithCommas = new WordsWithCommas(wordsList);
String result = wordsWithCommas.wordsWithCommas();
System.out.println(result); // Output: {one, two, three}
}
}
WordsWithCommas.main(null);
{One, Two, Three}
Question 38:
The first “if” block in the code checks to see if there is a match of the search variable (i.e. “v”) to the last variable in the array (as indicated by numVals - 1). This is recursive each call to mystery will back up this up one lower in the array.
The second “if” block checks to see if the array is only one long. If that’s the case, return and end. There is no more to process in the array.
The else of the second “if” block calls mystery again, but this time sets the numVals length one shorter (accounting for index 0). The mystery method runs again. If there is a match (i.e. first “if” block is true), k = 1 meaning that when the stack unwinds 1 will be added to the overall return value. The code…
The code segement return k + mystery(nums, v, numVals - 1);
adds the returned “1” to the existing value if ‘k’. This is how the code returns the number of elements in the variable numbers array that are equal to the value of the val variable.
public class MysteryClass {
public static int mystery(int[] nums, int v, int numVals) {
int k = 0;
if (v == nums[numVals - 1]) {
k = 1;
}
if (numVals == 1) {
return k;
}
else {
return k + mystery(nums, v, numVals - 1);
}
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 2, 4, 2, 5};
int val = 2;
int result = mystery(numbers, val, numbers.length);
System.out.println("Number of elements in numbers that are equal to val: " + result);
}
}
MysteryClass.main(null);
Number of elements in numbers that are equal to val: 3
Journey, Learning, Discovery (reflection)
2014 MC Results:
2015 MC Results:
Glows:
-
Array List: My array list percentage grew from 50% to 67%. Although that doesn’t sound like that big of an improvement, the number of questions are in play and the 2015 MCQ had 6 questions compared to 2014 MCQ’s 4 questions. The biggest unit I struggled with was I think array
-
2D Arrays: A major improvement was with my 2D arrays, as that was the biggest topic I struggled with in the 2014 MC. I previously had my mom help me understand the 2D arrays in the 2014 MC, which did help my understanding with 2D arrays. In the 2014 MC, I missed all 2 questions. In the 2015 MC, I only missed 1 out of the 4. There was definently an improvement in my understanding with 2D arrays.
-
Recursion: From the 2014 MC to the 2015 MC, my % correct with recursion jumped from 75% to 83%. This was additionally boosted by the fact that there were a greater number of recursion problems compared to the last exam. Although I missed a problem (question 38) that mainly focused on recursion, it had definently taught me to watch out for problems gave out big hints that it was on recursion.
-
Overall help: On this MC, I didn’t recieve help compared to the 2014 MC, which I thought was a major improvement.
Grows:
- Objects: As objects are throughout the entire course in CSA, I should not be missing on such a easy unit. Compared to the 2014 MC, I had the same % missed questions, but 2014 MC had double the # of questions. I have to mainly watch out for these questions, especially for dumb errors.
- Boolean Expressions and if Statements: Boolean questions, especially including DeMorgan’s laws, shouldn’t be too hard. I messed up because I rushed through this section due to time.
- Time: As we are given an hour and a half for the MCQ portion, I finished my test a bit over an hour. However, I feel like I spent way more time than I needed to on some questions. However, I think it comes down to understanding the material better.
Overall Analysis:
Upon reflecting on my recent College Board test, I noticed a couple of areas where I need to up my game. Keeping an eye on object types and Boolean types, especially De Morgan’s Law, is something I realized needs more attention. Arrays and array lists gave me a hard time in the last test, so I’m still working on getting the hang of them for the next one. On the bright side, I did see some progress in understanding arrays and recursion. Overall, I’ve got my sights set on smoothing out the rough spots and building on what’s going well for better performance in the upcoming tests.