FRQ
› csapa
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
intwith%and/inside a loop, and storing each one in anArrayList<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
Digitsclass has:private ArrayList<Integer> digitList— holds oneIntegerper digit, in the same order the digits appear in the original number- A constructor:
Digits(int num), with the preconditionnum >= 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
digitListmust end up with exactly oneIntegerper digit ofnum.- Those digits appear in
digitListin the same left-to-right order they appear innum. numcan be0, which has exactly one digit (0itself) — not zero digits.
Step-by-Step Approach
- Instantiate
digitListas a new, emptyArrayList<Integer>. - Handle
num == 0as a special case first: add a single0and stop there. - Otherwise, loop while
num > 0: peel off the last digit withnum % 10, insert it at the front ofdigitList(index0), then chop that digit off withnum = num / 10. - The loop naturally ends once
numreaches0.
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 ofnum.num = num / 10— integer division drops that last digit entirely, shrinkingnumby one digit each pass.digitList.add(0, digit)— digits come offnumin reverse order (last digit first), so inserting each new one at index0— 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 == 0special case — the loop conditionnum > 0is never true whennumis already0, so without this checkdigitListwould end up empty instead of holding the single digit0.
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 == 0special case. Without it,new Digits(0)produces an empty list instead of[0]. - Updating
numincorrectly — leaving outnum = num / 10(or writingnum % 10again instead) causes an infinite loop or repeats the same digit forever. - Creating the wrong collection type, such as
ArrayList<int>—intisn't a valid generic type parameter; it must be the wrapper classInteger.
Part (b): Writing isStrictlyIncreasing()
The Rule, Broken Down
- Compare every pair of adjacent digits in
digitList. - The moment any digit is not strictly greater than the one before it — including a tie — the whole list fails.
- If every adjacent pair passes, the list is strictly increasing.
Step-by-Step Approach
- Loop an index
ifrom0up to (but not including)digitList.size() - 1. - On each pass, compare
digitList.get(i)todigitList.get(i + 1). - If the current digit is greater than or equal to the next one, return
falseimmediately. - If the loop finishes without ever returning
false, returntrue.
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 twoIntegerobjects to compare them with>=, so no explicit conversion is needed.- The loop bound
digitList.size() - 1, notdigitList.size()— the loop comparesiagainsti + 1, so the last validiis 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
falseimmediately,trueonly 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) treat1336's repeated3as still "increasing," since3 > 3isfalseand 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
digitListlike an array (digitList[i]) instead ofdigitList.get(i)—ArrayListdoesn't support bracket indexing. - Using
digitList.size()as the loop bound instead ofdigitList.size() - 1, which would throw anIndexOutOfBoundsExceptiontrying to accessdigitList.get(i + 1)on the last iteration.
Key Takeaways
- Extracting digits from an
intright-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
0separately 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.