2023 AP CSA FRQ 4: BoxOfCandy Solution + Rubric

May 2026 exam uses a NEW point structure — tap for details

This page shows the original 2023 FRQ 4, which the College Board scored on a 9-point rubric. The May 2026 exam uses a NEW point distribution and structure — the patterns and traps on this page still apply, but expect different point values and formats on test day.

FRQ 1: 7 points (2 parts: Part A 4pts + Part B 3pts) — Methods & Control Structures

FRQ 2: 7 points (single part) — Class Design

FRQ 3: 5 points (single part) — Data Analysis with ArrayList

FRQ 4: 6 points (single part) — 2D Array

Total Section II: 25 points = 45% of exam score. Only Question 1 has two parts on the 2026 exam; Questions 2, 3, and 4 each have a single part.

Sources: Official College Board CED, Exam Overview (page 145) · Skylight Publishing CED Sample FR Solutions (page 161 reference)

2023 AP CSA FRQ 4: BoxOfCandy — Complete Solution & Rubric

Step-by-step solution to 2023 AP CSA FRQ 4 (BoxOfCandy) with the official 9-point rubric, common mistakes that cost points, and a built-in 22-minute practice timer. Written by an AP Computer Science teacher whose students earn 5s at more than 2x the national rate.

Year: 2023 Question: 4 of 4 Points: 9 Topics: 2D Array, Nested Loops Difficulty: Hard
Recommended pace: 22:00 per FRQ 22:00

The Official 2023 FRQ 4 Question

The complete prompt is in the PDF below. Use the recap above the editor to keep the key requirements in mind while you write your response.

The PDF cannot be embedded on this device.

Open Prompt PDF in New Tab

Write Your Part A Response: moveCandyToFirstRow

Read the prompt above and write your responses in the editors below — Part A in the first, Part B in the second. The real AP exam in Bluebook gives you the prompt and separate response areas per part with no requirement summary or hints. Practice like that here. When you’re done with both parts, click Reveal Solution & Scoring Rubric below to compare your code against the official rubric.

moveCandyToFirstRow.java Tab indents | Enter auto-indents | Brackets auto-close
Drag bottom-right corner to resize editor ⇲

Write Your Part B Response: removeNextByFlavor

removeNextByFlavor.java Tab indents | Enter auto-indents | Brackets auto-close
Drag bottom-right corner to resize editor ⇲

Ready to self-grade? Compare your code against the official 9-point rubric below. AP FRQs are graded by trained human readers, so we don’t auto-score — you’ll learn more by checking your work against the rubric criteria yourself.

What the Prompt Was Asking

Before reading the solution, check whether your response covered each of these requirements:

Write: public boolean moveCandyToFirstRow(int col) — Part A; public Candy removeNextByFlavor(String flavor) — Part B

Required behavior:

  • Part A moveCandyToFirstRow: first check if box[0][col] != null — if so, return true immediately. Otherwise loop down column col from row 1 to box.length - 1. When you find a non-null candy, copy it to box[0][col], set box[row][col] to null, return true.
  • Part A return logic: return true when EITHER row 0 already had candy OR a candy was successfully moved up. Return false ONLY after the loop exhausts the column with no candy found. Don't return false inside the loop — Sample 4B lost Point 4 for early-return.
  • Part B removeNextByFlavor: outer loop row from box.length - 1 DOWN to 0 (bottom-to-top), inner loop col from 0 to box[0].length - 1 (left-to-right). Guard against null with box[row][col] != null BEFORE calling getFlavor. Use .equals for String comparison. On match: save the Candy reference, set box[row][col] to null, return the saved reference. After both loops: return null.

How to Write the BoxOfCandy Methods Step-by-Step

// Sample solution adapted from official scoring guidelines
// 2023 AP CSA FRQ 4: BoxOfCandy (worth 9 points)

public boolean moveCandyToFirstRow(int col) {
    // If row 0 already has candy in this column, success
    if (box[0][col] != null) {
        return true;
    }
    // Search down the column for the first non-null candy
    for (int row = 1; row < box.length; row++) {
        if (box[row][col] != null) {
            box[0][col] = box[row][col];
            box[row][col] = null;
            return true;
        }
    }
    return false;  // Column had no candy
}

public Candy removeNextByFlavor(String flavor) {
    // Traverse BOTTOM-to-TOP, LEFT-to-RIGHT (per problem spec)
    for (int row = box.length - 1; row >= 0; row--) {
        for (int col = 0; col < box[0].length; col++) {
            // Null guard before calling getFlavor
            if (box[row][col] != null && box[row][col].getFlavor().equals(flavor)) {
                Candy found = box[row][col];
                box[row][col] = null;
                return found;
            }
        }
    }
    return null;
}

Official 9-Point Scoring Rubric for BoxOfCandy

Pts Criterion
+1 Accesses elements of column col
+1 Compares box[0][col] to null before searching
+1 Identifies and moves a candy to the first row, nulling original (algorithm, Part A)
+1 Returns appropriate boolean (true on success/already-there, false if no candy in column)
+1 Traverses box BOTTOM-to-TOP, LEFT-to-RIGHT (correct loop directions)
+1 Null-checks box[row][col] before calling getFlavor()
+1 Calls getFlavor() on Candy objects
+1 Compares flavor with .equals(flavor) (not ==)
+1 Replaces matching Candy with null and returns it (algorithm, Part B)

Common Mistakes That Cost Points on FRQ 4

Mistake 1: Traversing top-to-bottom in Part B instead of the required bottom-to-top order. Sample 4B and Sample 4C in the official commentary both lost Point 5 because they traversed top-to-bottom. The prompt explicitly requires bottom-to-top traversal — outer loop must START at the LAST row and DECREMENT. The correct pattern: for (int row = box.length - 1; row >= 0; row--). Always read traversal-order specifications precisely; defaulting to standard top-down breaks the rubric requirement.
Mistake 2: Failing to null-check before calling getFlavor on a Candy object. Sample 4A and Sample 4B in the official commentary both lost Point 6 because there was no check to determine if box[row][col] is null before accessing its flavor. The 2D array can contain null references — calling getFlavor on null throws NullPointerException. Always guard with if (box[row][col] != null && box[row][col].getFlavor().equals(flavor)) — short-circuit evaluation prevents the crash.
Mistake 3: Returning false too early in Part A's loop. Sample 4B in the official commentary lost Point 4 because of an early return — false should not be returned until the entire column has been searched. The pattern: only return true on success (inside the if when candy is found); place return false AFTER the loop completes. Returning false inside the loop on the first non-match exits before checking the remaining rows.
Mistake 4: Replacing the moved Candy in Part A but failing to set the original location to null. Sample 4A in the official commentary explicitly notes Point 3 requires that the response 'replace the moved Candy object with null.' Just copying box[row][col] to box[0][col] leaves both positions pointing to the same Candy — the candy is duplicated, not moved. The fix is two assignments: box[0][col] = box[row][col]; box[row][col] = null;
Mistake 5: Calling .equals with the wrong argument or using == for String comparison. Sample 4B in the official commentary lost Point 8 because the argument to equals was String.flavor instead of just flavor. The correct call is candy.getFlavor().equals(flavor) — the parameter to compare to is just the variable name, no qualifier. And NEVER use == for String comparison in AP CSA — it compares references, not contents. The rubric explicitly disqualifies == for Point 8.
Key Insight: BoxOfCandy teaches the most-overlooked detail in 2D-array FRQs: traversal order specification. Sample 4B and Sample 4C BOTH lost Point 5 by ignoring the prompt's bottom-to-top requirement and defaulting to standard top-down. Whenever a 2D-array prompt specifies an unusual traversal order (bottom-to-top, right-to-left, diagonal, spiral), translate that DIRECTLY into your loop bounds: bottom-to-top means start at length - 1 and decrement; right-to-left means start at length - 1 and decrement on the inner loop. Skim past this requirement and you've lost Point 5 before writing a single line. A second insight specific to nullable 2D-array references: when the array stores OBJECTS (not primitives), you MUST null-check before calling any method on those objects. Sample 4A and 4B both lost Point 6 by skipping this guard. The defensive pattern using short-circuit AND: if (box[row][col] != null && box[row][col].getFlavor().equals(flavor)) — Java evaluates left-to-right and stops on the first false, so the null check protects the method call. This pattern recurs across every FRQ involving arrays of objects (2018 WordPairList, 2021 ClubMembers, 2022 ReviewAnalysis), and skipping it produces NullPointerException at runtime.

FAQs About 2023 AP CSA FRQ 4

What does 2023 AP CSA FRQ 4 BoxOfCandy test?

BoxOfCandy tests two methods on a 2D array of Candy references: moveCandyToFirstRow (Part A) checks if a column's first row has candy; if not, it searches down the column for a Candy object, moves it to row 0, and returns true; removeNextByFlavor (Part B) traverses the box BOTTOM-to-TOP, LEFT-to-RIGHT, finds the first Candy whose flavor matches the parameter, removes it (sets to null) and returns it. The hardest single point is Point 5: the bottom-to-top, left-to-right traversal order — Sample 4B and Sample 4C both lost Point 5 by traversing top-to-bottom instead.

How many points is FRQ 4 worth?

9 points, awarded across the rubric criteria. FRQ 4 makes up about 11% of the AP CSA exam score.

What is the most common mistake on 2023 FRQ 4 BoxOfCandy?

Traversing the 2D array top-to-bottom in Part B instead of the specified bottom-to-top order. Sample 4B and Sample 4C in the official commentary both lost Point 5 because they traversed in the default top-down direction. The prompt explicitly requires starting from the LAST row. The correct outer loop is: for (int row = box.length - 1; row >= 0; row--) — start at the last row, decrement until 0. Always read the prompt's traversal order specification carefully.

How long should I spend on FRQ 4?

Aim for 22 minutes per FRQ. The AP CSA free-response section is 90 minutes for 4 questions, so 22 minutes per question leaves a 2-minute buffer to review.

Is BoxOfCandy still relevant for the 2026 AP CSA exam?

Yes. The current AP CSA 4-unit curriculum still tests 2D array traversal with nested loops, so BoxOfCandy is excellent practice for the 2026 exam format.

Where can I find the official scoring guidelines?

College Board publishes the official scoring guidelines as a PDF on AP Central. The rubric on this page mirrors those criteria. You can download the official scoring guidelines here.

Related AP CSA FRQs to Practice Next

If you found BoxOfCandy useful, work through these next to lock in the same Java concepts:

Why 2023 FRQ 4 Still Matters for the 2026 AP CSA Exam

The 2026 AP CSA curriculum reorganized the topic list into 4 units, but the FRQ types stayed the same. 2023 FRQ 4 (BoxOfCandy) tests 2D array traversal with nested loops, which is still a core part of the exam. Practicing this question prepares you for the Bluebook digital test format and builds the muscle memory you need for the exam on Friday, May 15, 2026.

Get in Touch

Whether you're a student, parent, or teacher — I'd love to hear from you.

Just want free AP CS resources?

Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.

Typically responds within 24 hours

Message Sent!

Thanks for reaching out. I'll get back to you within 24 hours.

🏫 Welcome, fellow educator!

I offer curriculum resources, practice materials, and study guides designed for AP CS teachers. Let me know what you're looking for — whether it's classroom materials, a guest speaker, or Teachers Pay Teachers resources.

Email

[email protected]

📚

Courses

AP CSA, CSP, & Cybersecurity

Response Time

Within 24 hours

Prefer email? Reach me directly at [email protected]