CompSci.rocks
FRQcsapa

Digits: 2017 FRQ 1

A step-by-step solution to the 2017 AP CSA FRQ 1 (Digits), covering extracting the digits of an integer into an ArrayList and checking whether they're strictly increasing in Java.

Pulling an integer apart into its individual digits — and then checking whether those digits climb steadily upward — is the job of this AP Computer Science A free-response question, built entirely around a single ArrayList field.

What This FRQ Tests

  • AP CSA units: Unit 7 (ArrayList) and Unit 4 (Iteration)
  • Core skill: extracting the digits of an int with % and / inside a loop, and storing each one in an ArrayList<Integer>
  • Secondary skill: traversing a list and comparing each element against its neighbor
  • Official category: "Array/ArrayList," which on the 2017 exam was FRQ 1 (the fixed FRQ 1–4 category order used in more recent years — Methods and Control Structures, Classes, Array/ArrayList, 2D Array, always in that sequence — wasn't standardized until the 2019–2020 Course and Exam Description redesign; 2017's actual printed order was Digits, MultPractice, Phrase, Successors)

The Setup

  • The given Digits class has:
    • private ArrayList<Integer> digitList — holds one Integer per digit, in the same order the digits appear in the original number
    • A constructor: Digits(int num), with the precondition num >= 0
    • boolean isStrictlyIncreasing() — to be written
  • You're asked to write both the constructor and isStrictlyIncreasing().

Part (a): Writing the Constructor

The Rule, Broken Down

  1. digitList must end up with exactly one Integer per digit of num.
  2. Those digits appear in digitList in the same left-to-right order they appear in num.
  3. num can be 0, which has exactly one digit (0 itself) — not zero digits.

Step-by-Step Approach

  1. Instantiate digitList as a new, empty ArrayList<Integer>.
  2. Handle num == 0 as a special case first: add a single 0 and stop there.
  3. Otherwise, loop while num > 0: peel off the last digit with num % 10, insert it at the front of digitList (index 0), then chop that digit off with num = num / 10.
  4. The loop naturally ends once num reaches 0.

The Code

public Digits(int num)
{
    digitList = new ArrayList<Integer>();

    if (num == 0)
    {
        digitList.add(0);
    }

    while (num > 0)
    {
        int digit = num % 10;
        digitList.add(0, digit);
        num = num / 10;
    }
}

Why Each Piece Matters

  • num % 10 — the remainder after dividing by 10 is always the current last digit of num.
  • num = num / 10 — integer division drops that last digit entirely, shrinking num by one digit each pass.
  • digitList.add(0, digit) — digits come off num in reverse order (last digit first), so inserting each new one at index 0 — pushing everything else one spot to the right — is what puts them back in the correct left-to-right order by the time the loop finishes.
  • The num == 0 special case — the loop condition num > 0 is never true when num is already 0, so without this check digitList would end up empty instead of holding the single digit 0.

Tracing the Example

Digits d1 = new Digits(15704):

Step num before Digit peeled (num % 10) digitList after add(0, digit) num after /= 10
1 15704 4 [4] 1570
2 1570 0 [0, 4] 157
3 157 7 [7, 0, 4] 15
4 15 5 [5, 7, 0, 4] 1
5 1 1 [1, 5, 7, 0, 4] 0 (loop ends)

Final digitList: [1, 5, 7, 0, 4] — matches the question's Example 1 exactly.

Digits d2 = new Digits(0) hits the special case directly, producing digitList = [0] — matching Example 2.

Common Mistakes to Avoid

  • Appending each digit to the end of the list (digitList.add(digit)) instead of inserting at the front. Since digits come off in reverse order, this produces the digits backwards.
  • Forgetting the num == 0 special case. Without it, new Digits(0) produces an empty list instead of [0].
  • Updating num incorrectly — leaving out num = num / 10 (or writing num % 10 again instead) causes an infinite loop or repeats the same digit forever.
  • Creating the wrong collection type, such as ArrayList<int>int isn't a valid generic type parameter; it must be the wrapper class Integer.

Part (b): Writing isStrictlyIncreasing()

The Rule, Broken Down

  1. Compare every pair of adjacent digits in digitList.
  2. The moment any digit is not strictly greater than the one before it — including a tie — the whole list fails.
  3. If every adjacent pair passes, the list is strictly increasing.

Step-by-Step Approach

  1. Loop an index i from 0 up to (but not including) digitList.size() - 1.
  2. On each pass, compare digitList.get(i) to digitList.get(i + 1).
  3. If the current digit is greater than or equal to the next one, return false immediately.
  4. If the loop finishes without ever returning false, return true.

The Code

public boolean isStrictlyIncreasing()
{
    for (int i = 0; i < digitList.size() - 1; i++)
    {
        if (digitList.get(i) >= digitList.get(i + 1))
        {
            return false;
        }
    }

    return true;
}

Why Each Piece Matters

  • digitList.get(i) >= digitList.get(i + 1) — Java automatically "unboxes" the two Integer objects to compare them with >=, so no explicit conversion is needed.
  • The loop bound digitList.size() - 1, not digitList.size() — the loop compares i against i + 1, so the last valid i is the second-to-last index; going one further would try to access an index that doesn't exist.
  • >=, not >, for the failing condition — the problem defines "strictly increasing" as each digit being greater than (but not equal to) the one before it, so a tie must fail the check.
  • Returning false immediately, true only after the loop — this correctly requires every pair to pass, not just the first one checked.

Tracing the Example

Method call Digits First failing pair Result
new Digits(7).isStrictlyIncreasing() [7] none (only one digit, loop never runs) true
new Digits(1356).isStrictlyIncreasing() [1,3,5,6] none (1<3<5<6) true
new Digits(1336).isStrictlyIncreasing() [1,3,3,6] index 1 vs. 2: 3 >= 3 false
new Digits(1536).isStrictlyIncreasing() [1,5,3,6] index 1 vs. 2: 5 >= 3 false
new Digits(65310).isStrictlyIncreasing() [6,5,3,1,0] index 0 vs. 1: 6 >= 5 false

All five results match the question's table exactly.

Common Mistakes to Avoid

  • Using > instead of >= for the failure check. This would (incorrectly) treat 1336's repeated 3 as still "increasing," since 3 > 3 is false and would slip past the check.
  • Returning inside the loop with an if (...) return false; else return true; pattern. This exits after checking only the very first pair, so it never actually verifies the rest of the list — a genuine mistake the official scoring guidelines call out by name.
  • Accessing digitList like an array (digitList[i]) instead of digitList.get(i)ArrayList doesn't support bracket indexing.
  • Using digitList.size() as the loop bound instead of digitList.size() - 1, which would throw an IndexOutOfBoundsException trying to access digitList.get(i + 1) on the last iteration.

Key Takeaways

  • Extracting digits from an int right-to-left with % and /, then inserting each one at the front of the list, is the standard pattern for ending up with them in left-to-right order.
  • Always special-case a value like 0 separately whenever a loop condition (num > 0) would otherwise skip it entirely, since it still needs to be represented.
  • "Strictly increasing" (or decreasing) checks compare every adjacent pair and fail immediately on the first tie or reversal — never wait until the end and assume a tie is fine.

Related FRQs