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.
Need help preparing for the AP exam?
FRQs are one of the toughest parts of the AP CS exam. I offer 1-on-1 tutoring to help you work through practice problems, tighten up your responses, and build the confidence to earn full credit on exam day.
Book a tutoring session →