<< Hide Menu

πŸ“š

Β >Β 

πŸ’»Β 

Β >Β 

πŸ“š

AP Computer Science A Exam Guide

14 min readβ€’june 18, 2024

Avanish Gupta

Avanish Gupta

Avanish Gupta

Avanish Gupta

The AP CSA Multiple Choice Section

It's finally time. You've mastered creating classes, excel at arrays and ArrayLists, and dance around every control structure type. Now, you're ready for the AP CSA test! The first part of the test is theΒ multiple choice section. This multiple choice section isΒ 40 questionsΒ inΒ 90 minutesΒ withΒ 5 choices each (A-E). Here are the distributions of the units on the multiple choice section:

AP CSA MC Unit Descriptions

Unit NumberUnit NamePercentNumber of Questions
1Primitive Types2.5-5%1-2
2Using Objects5-7.5%2-3
3Boolean Expressions and If Statements15-17.5%6-7
4Iteration17.5-22.5%7-9
5Writing Classes5-7.5%2-3
6Array10-15%4-6
7ArrayList2.5-7.5%1-3
82D Array7.5-10%3-4
9Inheritance 5-10%2-4
10Recursion5-7.5%2-3

Multiple Choice Tips

There are two tips that are very useful for AP CSA Multiple Choice Questions:

Trace and Annotate

Tracing the code means following the code line by line, iteration by iteration to see what happens in the program. While doing this, take note of the values of variables so that you don't lose track of what is happening by annotating, writing these values down on your test booklet. Although this may take some time, you have over 2 minutes a question, and this should be more than enough time to trace the code as you go.

Process of Elimination

Process of elimination is one of the most useful tools for AP CSA. You can get rid of many answer choices by paying attention to the types and classes of the methods and objects in question. Sometimes the answer choices will have types or logic that will make no sense which will allow us to cross them out and eliminate them! For example, you will be able to eliminate A, C, and D because they don't make sense, leaving us with only B and E! Now, instead of having a 20% of guessing the correct answer, you now have a 50% chance of doing so! This is a significant increase! Sometimes, you may even be able to narrow it down to one answer, and this will be your correct answer!

The Multiple Choice from the Course and Exam Description

Below are the multiple-choice example questions from theΒ College Board Course and Exam DescriptionΒ with detailed explanations.

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-6kYCp5PRI5Lg.png?alt=media&token=980003b6-045b-4bf1-b5c6-e6c2ad4e24f4

Answer

Here, we are going to evaluate the expression in the print statement step-by-step

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FScreen%20Shot%202020-09-05%20at%2012.48-OOY16Na45iSh.png?alt=media&token=88af6340-93ef-495a-92c6-eed564db9e6c

Thus C is the correct answer.

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-cfqQALlXZgQ2.png?alt=media&token=37ebe8f4-372a-4fce-a213-c94b4e6485a4

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-mbVbfBFQQHdW.png?alt=media&token=dc04df53-6e6e-4e0d-8559-19073c3d4ee4

Answer

Since we are printing an indexOf method result, the answer will be an integer, so we can eliminate D and E. Now we just trace the code as follows:

Line 1: gets the first 2 letters of word1 and saves it as str1

Line 2: gets the last letter of word2 and saves it as str2

Line 3: makes a new string result by putting str2 at the beginning and str1 after

Line 4: Finds where str2 is in result, because it is at the beginning, the integer that is printed isΒ 0

A is the correct answer

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-90AqZzBnzKIu.png?alt=media&token=823c21a7-0d8a-4984-82af-a24770df9514

Answer

The Math.random() method returns a random number that is greater than or equal to 0.0 and less than 1. There are 36 integers between 25 and 60 inclusive is 36, which we multiply by Math.random() in the line of code to give this range. This eliminates choices A, B, C, and E. From process of elimination, that leaves us with choice D.

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-DSSTulSTOIYa.png?alt=media&token=72338fc9-9a3a-4c3a-9f6a-ab1b54c1290c

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-pPFbGffHdyQ7.png?alt=media&token=e7377092-5c1c-4836-a604-43eb71fc8afb

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-5fKV35CiwsKq.png?alt=media&token=7919ba97-8c0e-4f2f-ad80-48fc6fce1192

Answer

This method sorts Large and Mid-Size vehicles correctly because their if-statement conditionals correctly distinguish these types, but for all other categories, since their volume is less than 120 for the second if-statement conditional, this method will incorrectly classify them as Mid-Size. The only choice that are in the correct classifications is E.

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-92JeKB40J52A.png?alt=media&token=89124bfb-2dea-456f-9687-360f9bbab6aa

Answer

This statement is true when either a is true (a) AND the inverse of (b OR a) (!(b || a)) is true. Let's do a truth table to represent this as follows:

Truth Table

Value of aValue of bValue of (b or a)Value of !(b or a)Value of (a and !(b or a))
falsefalsefalsetruefalse
falsetruetruefalsefalse
truefalsetruefalsefalse
truetruetruefalsefalse

Recall that for the OR operator, only one of the two values on each side has to be true and for the AND operator, both sides have to evaluate to true. From the truth table, we can see that the final expression always evaluates to false with all possible inputs. Thus the correct answer is B.

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-qGnSmHRolG5j.jpg?alt=media&token=5d02cfe6-fdfe-4949-bc86-972ec807143a

Answer

To answer this question, we trace the code and annotate as shown below.

val = 48, div = 6, 48 % 2 == 0, 6 > 0, 48 % 6 == 0
"48 " is printed
val = 24, div = 5, 24 % 2 == 0, 5 > 0, 24 % 5 != 0
val = 12, div = 4, 12 % 2 == 0, 4 > 0, 12 % 4 == 0
"48 12 " is printed
val = 6, div = 3, 6 % 2 == 0, 3 > 0, 6 % 3 == 0
https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-PgVWf8aFiW6w.png?alt=media&token=a1e1fbe7-d9d9-42c9-8d47-406a1e884081

Answer

For the result to be used in another class, we need public access, and to even use the integer, we need the method to return an int. The only choice that achieves this is C.

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-TlgSFTMtsJWw.png?alt=media&token=9904493b-0f37-4c5d-bc01-94ae74c2b362

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-kz5NTwlgdmaC.png?alt=media&token=471e6264-eb08-49c5-beea-662a780d77a8

Answer

The error here is in the loop header where the Boolean expression is. The way it is right now, it allows i = animals.length, which will throw an ArrayIndexOutOfBounds exception since the last index is animals.length - 1. The fix to this is to remove the equality, which matches A.

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-PmSH0BUnYgPq.png?alt=media&token=b1a7cf90-5fe7-4fa7-90b7-6ea8b74b4875

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-iLVdAjdipwXT.png?alt=media&token=c6f8f737-b2d6-4f01-b2d3-05de3b8adec6

Answer

I will not work because k is not incremented, creating an infinite loop. II works as the loop header is correct so that the loop actually traverses through the array and the array values are actually updated. III will not work because even though n is updated, Java is pass-by-value, so the array value is not updated. Only II works, so the answer is A.

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-8wdct5XQ3CMt.png?alt=media&token=b63ced6f-8b04-4d5c-9a6e-c8caf2f1ccc1

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-PJF38rjcEKtv.png?alt=media&token=fc830be9-465b-4dfe-ba21-de114aa9dfde

Answer

This will require some code tracing. Here, I have written the code line by line with the contents of the array after each line. On the actual test on the test booklet, I would make an array and add elements as we go as well as cross out removed elements and add arrows to elements added in the middle of the array.

After Line 2: ["one"]
After Line 3: ["one", "two"] 
After Line 4: ["three", "one", "two"]
After Line 5: ["three", "one", "four"]
After Line 6: ["three", "one", "four", "five"]
After Line 7: 
https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-eCBqJDRz3j1Q.png?alt=media&token=5ced85f0-c419-4ce9-9072-0291081ed87c

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-W9coYRE6Rzw3.png?alt=media&token=118ba3cc-53e9-4fd9-8dcd-9cbc5480ea29

Answer

So what happens to the list?Β When there is an even element, the item that would be next would now be in the previous index, but sinceΒ iΒ is incremented, the method skips that next item, which corresponds with E. Here is an example of what would happen:

// Suppose we have an ArrayList myList = [1, 2, 3, 5] and let's call // removeEvens on this ArrayList. // When i = 0, the element myList.get(0) = 1 is not even, so the array is // untouched. // When i = 1, the element myList.get(1) = 2 is even, so the 2 is removed // and all the elements will shift to the left, so myList is now [1, 3, 5] // When i = 2, the element myList.get(2) = 5, but we have skipped 3 because // it is now at index 1 but i is looking for the new element at index 2!

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-qeApR9bo1n1K.png?alt=media&token=3bc0e048-5f25-4ca1-81cb-93bededf97e2

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-XKNsm2HPmTMb.png?alt=media&token=2eb9ec7f-54f0-47d5-9195-a961b9c9b104

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-95TMuEaqSK7k.png?alt=media&token=c09dc9d9-27c7-461c-abe8-455f79395993

Answer

We will need to trace some code here.

points.length = 4, points[0].length = 5;
row = 0
col = 4, 4 >= 0, "15 " printed
col = 3, 3 >= 0, "15 14 " printed
col = 2, 2 >= 0, "15 14 13 " printed
col = 1, 1 >= 0, "15 14 13 12 " printed
col = 0, 1 >= 0, 
https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-zYkNrGo6VNQD.png?alt=media&token=ee62c76f-94e8-4e88-a8c3-97af0137f895

Answer

This question requires some more code tracing.

sum = 0
x = {1, 2, 3, 4} (x.length - 1 will always be 3)
y = 0, sum = 1, y = 1, sum = 3, y = 2, sum = 6, y = 3, 3 !< 3
We now move to a new row and repeat.
The method adds every number in the 2D array except from the last
column, which will turn out to be 54, 
https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-FjKjhk5RJ1fg.png?alt=media&token=be3878f1-66a6-4b16-85e5-26bbcac006fa

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-4jKln8SVvU9N.png?alt=media&token=c3bcf96a-4904-4e25-bd14-abc8b16e9ebd

Answer

The static type of t is Thing1, while the dynamic type of t is Thing2. Since calc() is not a static method, the Thing2 version of calc() is used. Now we code trace.

IN THING2 CALC:
n = 2 -> 4
super.calc() -> use the calc method in the parent class, which is Thing1
THING1 CALC IS CALLED, IN THING1 CALC:
n = 4 -> 12, "12" is printed
BACK IN THING2:
n = 4, 
https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-31Jg7QOfjt9l.png?alt=media&token=ac299dba-fde0-460e-9bf6-206a6ffaa152

https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-ix31wU6XObyB.png?alt=media&token=f262efec-d677-4ee2-a074-75aa370120d8

Answer

TheΒ recursive codeΒ mystery1 with its call to itself adds 5 to the sum if n is greater than 1, and then adds 1 when n = 1, which is the base case. Remember that we can To achieve this with the looped code, mystery2, we need to initialize total to be 1, which is A.

The AP CSA Free Response Questions

You've finished the multiple-choice section of the exam, and after a short break, it's time for the second half of the test: the FRQ section. The FRQ section hasΒ 4 different FRQsΒ inΒ 90 minutes, the same amount of time as the multiple-choice portion.

Types of FRQs

The AP CSA test has 4 FRQs, each of which is different in style. Here's a little bit about them:

  1. Methods and Control Structures

    This FRQ asks you to write methods and master control structures such as loops and branching (if/else if/else).

  2. Class Writing

    This FRQ asks you to write an entire class, given specifications of what the class should do, and including any variables and methods the class should include.

  3. Array/ArrayList

    This FRQ asks you to write methods that use an array or ArrayList, including filtering and traversal. In recent years, the questions tend to be more about ArrayLists than standard arrays.

  4. 2D Arrays

    This FRQ asks you to write methods that use a 2D array, including traversal of arrays.

AP CSA FRQ Task Verbs

  • Assume: Suppose that the statement is true without any further information. For example, in later parts of a question, we can assume that the code written in earlier parts works as intended.
  • Complete (program code): Sometimes, there is code that is partially filled. It is your job to finish the code so that it works as intended.
  • Implement/Write:Β When doing this, we write a whole class or method, given what it is supposed to do.

FRQ Tips

Here are some tips that you should follow to ace the AP CSA FRQs.

Skip Parts You Don't Know

For all the multi-part questions on the FRQ, the later parts always state to refer to a past method that you have coded in an earlier part. Even though you may not know how to code this earlier method, you can still answer this question because you can assume that prior code works. This will prevent you from losing points twice because the earlier method is incorrect, thus preventingΒ double jeopardy. It saves a lot of time and you can jump back to the earlier part if you have time left!

Write Pseudocode Before Starting to Write the Final Solution

Before jumping to the actual question, write pseudocode as a multi-line comment so you can plan what you are going to do and what is needed for the code. It will also keep you from missing necessary components and keeps your future code organized when finally answering the question and writing real Java code.

Make Up Some Test Cases

If you are unsure of whether your solution is correct, make up some test cases and test the code that you have written on these different test cases. If you get the expected result for all the test cases, then your code is most likely correct. If not, then go back to the point where the code did not work as expected and see how you can correct it.

Solving the 2019 AP CSA FRQs

TheΒ 2019 AP CSA FRQsΒ are the most recent set that matches the format set by the Course and Exam Description. They are solved below with the rationale and pseudocode included.

  1. Methods and Control Structures
  2. https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-hKupOS0YuGtk.png?alt=media&token=045e0b22-36cc-48b3-98a0-eef660eb0887

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-oy4m3PLEorMF.png?alt=media&token=dbef3eca-8284-4bf9-a7ae-cbfbf8c9c1ea

    Answer to 1a

    /** Returns the number of leap years between year1 and year 2 inclusive * Precondition: 0 <= year1 <= year2 */ public static int numberOfLeapYears(int year1, int year2) { /* Pseudocode: start looping from year 1 to year 2 inclusive, set a counter and add to the counter if isLeapYear(year) is true */ int counter = 0; for (int i = year1; i <= year2; i++) { if isLeapYear(i) { counter++; } } return counter; }

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-rU0oby2cOKJa.png?alt=media&token=fb1aa03f-c382-4749-b3e0-8b04dbdfe3a1

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-4ye6hJQeBzWI.png?alt=media&token=661e8533-303f-493c-a8a6-b97fbe544029

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-YSPznOoZgUHL.png?alt=media&token=e9ca089a-caa6-47c0-914e-bdb59b2cb0c5

    Answer to 1b

    /** Returns the value representing the day of the week for the given date

    * (month, day, year), where 0 denotes Sunday, 1 denotes Monday, ..., and 6 denotes Saturday

    * Precondition: The date is a valid date.

    */

    public static int dayOfWeek(int month, int day, int year) {

    /* Pseudocode first attempt: Use dayOfYear to figure out how many days of the year it has been

    in the year, and then modulo 7 to figure out how many days it has been,

    then subtract 1 because January 1st is 1 and not 0 and add firstDayOfYear()

    However, this may return a value larger than 6, which is outside our

    desired range for the output so we should add firstDayOfYear()

    and subtract 1 first before doing modulo to get the correct answer

    */

    return (dayOfYear(month, day, year) - 1 + firstDayOfYear(year)) % 7;

    }

  3. Class Writing
  4. https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-KutLbHUzJNgk.png?alt=media&token=93e42090-61f8-4c7a-b57f-8528d5a56a6a

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-hHfzczm5Hfny.png?alt=media&token=662a7824-4e21-4c24-a7b5-0db985ab11e5

    Answer to 2

    /** Tracks steps walked

    */

    public class StepTracker {

    private int totalDays;

    private final int ACTIVESTEPS;

    private int activeDayCount;

    private int totalSteps;

    /** Creates a StepTracker with activeSteps specified and other necessary instance

    * variables, including total steps, active days, and total days.

    */

    public StepTracker(int activeSteps) {

    ACTIVESTEPS = activeSteps;

    totalDays = 0;

    activeDayCount = 0;

    totalSteps = 0;

    }

    /** Adds a day of steps to total steps and also checks if there is an active

    * day. Also increments the total number of days

    */

    public void addDailySteps(int stepsInDay) {

    totalDays++;

    totalSteps += stepsInDay;

    if (stepsInDay >= ACTIVESTEPS) {

    activeDayCount++;

    }

    }

    /** Returns the number of active days

    */

    public int activeDays() {

    return activeDayCount;

    }

    /** Returns the average steps a day

    */

    public double averageSteps() {

    return (double) totalSteps / totalDays;

    }

  5. Array/Array List
  6. https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%203-F16OvQhSj8Om.png?alt=media&token=451d11f9-1dc3-4a42-ac73-f7c519d7b76c

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%203-LYyHl8UTK9j3.png?alt=media&token=97a80f74-38ad-4e5c-81ff-6be024da647c

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%202-U7Kxd5hZwqsb.png?alt=media&token=540e20f0-4a3a-4bd6-870c-6dc508b23132

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%203-hVUEPjzxz7ZG.png?alt=media&token=6cf91c0c-ff90-4132-9d2b-3c488d015644

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F3-3rKJ2lOyG1m2.png?alt=media&token=7be21461-84cc-49b7-aa46-e0b4fb5ae92c

    Answer to 3a

    /** Returns an ArrayList of delimiters from the array tokens

    */

    public ArrayList<String> getDelimitersList(String[] tokens) {

    /* Traverse through the array, if a token is a delimiter, add it to the ArrayList

    */

    ArrayList<String> delimiterList = new ArrayList<String>()

    for (String token: tokens) {

    if (token.equals(openDel) || token.equals(closeDel)) {

    delimiterList.add(token);

    }

    }

    return delimiterList;

    }

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%203b-rLvD4MNnACN8.png?alt=media&token=e69ddba1-6270-4c33-9b7d-d3b7c105f9be

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%203b-qwQeGP5ipBAG.png?alt=media&token=eeec55f4-fcfb-4837-aafd-8bcc60056ab3

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%203b-GY4EEq2g6IEl.png?alt=media&token=0dd75357-24e7-4a43-95a6-88e845e72246

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%203b-3JDqayt9H832.png?alt=media&token=026945a1-0d53-44dc-8c4e-0c8e8a746871

    Answer to 3b

    /** Returns true if the delimiters are balanced and false otherwise

    Precondition: delimiters contains only valid open and close delimiters.

    */

    public boolean isBalanced(ArrayList<String> delimiters) {

    /* Pseudocode: Set a counter, which represents the number of unpaired

    delimiters to 0 and for every open delimiter, add 1,

    for every close delimiter, subtract 1, representing an open

    delimiter has been paired return false if there is a close

    delimiter when the counter is 0 (no open to pair with) or the counter

    is not 0 in the end (not equal), else, return true

    */

    int openCount = 0;

    for (String delimiter: delimiters) {

    if (delimiter.equals(openDel)) {

    openCount++;

    } else {

    if (openCount == 0) {

    return false;

    } else {

    openCount--;

    }

    }

    }

    return openCount == 0;

    }

  7. 2D Array
  8. https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%204-UOYLQbLE63cG.png?alt=media&token=31badb54-2270-43d7-8c05-9ff8cd88f8cc

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2FCSA%204-lvqdn6seA30k.png?alt=media&token=2ffd4618-08bd-4695-be6b-beb0b29d141d

    Answer to 4a

    /** Constructs a LightBoard object having numRows rows and numCols columns.

    * Precondition: numRows > 0, numCols > 0

    * Postcondition: each light has a 40% probability of being set to on.

    */

    public LightBoard(int numRows, int numCols) {

    /* Traverse through each cell in the 2D array, for each cell, generate a random

    integer from 0 to 9, if this integer < 4, set to true, else set to false

    */

    import java.util.Random;

    Random rand = new Random();

    lights = new boolean[numRows][numCols];

    for (int i = 0; i < numRows, i++) {

    for (int j = 0; j < numCols; j++) {

    if (rand.nextInt(10) < 4) {

    lights[i][j] = true;

    }

    }

    }

    }

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-dXUC5RNNHEJE.png?alt=media&token=776f801c-8aab-4c4f-9ba0-e8d6560b2e3e

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-fidDrYerc8QP.png?alt=media&token=05e8ec48-deb0-428b-964a-13026248ef6f

    https://firebasestorage.googleapis.com/v0/b/fiveable-92889.appspot.com/o/images%2F-phKgVCDWmyik.png?alt=media&token=308d2ac2-216c-4a69-916c-7a8e6aa068d1

    Answer to 4b

    /** Evaluates a light in row index row and column index col and returns a status

    * Precondition: row and col are valid indexes in lights.

    */

    public boolean evaluateLight(int row, int col) {

    /* First count the ons on the column, then check the status of the light in question

    and proceed from there as in the instructions

    */

    int columnCount = 0;

    for (boolean[] row: lights) {

    if (row[col]) {

    columnCount++;

    }

    if (lights[row][col] && columnCount % 2 == 0) {

    return false;

    } else if (!lights[row][col] && columnCount % 3 == 0) {

    return true;

    }

    return lights[row][col];

    }