CompSci.rocks
FRQcsapa

DogWalker: 2025 FRQ 1

A step-by-step solution to the 2025 AP CSA FRQ 1 (DogWalker), covering capping a value against a maximum and building on a method across an hourly range in Java.

Paying a dog walker by the hour, dog, and bonus conditions is the scenario behind this AP Computer Science A free-response question — you first figure out how many dogs a single walker actually takes out in one hour, then reuse that logic to total up an entire shift's pay.

What This FRQ Tests

  • AP CSA units: Unit 3 (Boolean Expressions and if Statements), Unit 4 (Iteration), and Unit 5 (Writing Classes/methods)
  • Core skill: capping a value at a maximum using an if/else, and using two given helper methods together correctly
  • Secondary skill: looping across a range of hours and building on a method you already wrote, rather than duplicating its logic
  • Official category: "Methods and Control Structures" — always FRQ 1 on the AP CSA exam

The Setup

  • The given DogWalkCompany class (not modified) provides two helper methods:
    • int numAvailableDogs(int hour) — how many dogs need walking that hour (always greater than 0)
    • void updateDogs(int hour, int numberDogsWalked) — records that this many of that hour's dogs have been claimed
  • DogWalker holds:
    • private int maxDogs — the most dogs this walker can handle at once
    • private DogWalkCompany company — the company this walker is signed up with
  • You're asked to write two methods:
    • int walkDogs(int hour) — walks as many dogs as possible during one hour, capped at maxDogs
    • int dogWalkShift(int startHour, int endHour) — runs a whole shift and totals the pay earned

Part (a): Writing walkDogs(int hour)

The Rule, Broken Down

  1. Find out how many dogs the company has available that hour.
  2. The walker takes all of them, unless that's more than maxDogs — in which case the walker takes exactly maxDogs.
  3. Tell the company how many dogs were claimed, so no other walker double-books them.
  4. Return how many dogs this walker actually took.

Step-by-Step Approach

  1. Call numAvailableDogs(hour) to find out how many dogs need walking.
  2. Compare that to maxDogs: if the available count fits within the walker's capacity, walk all of them; otherwise, cap it at maxDogs.
  3. Call updateDogs(hour, ...) with however many dogs this walker is claiming, so the company's count stays accurate.
  4. Return that same number.

The Code

public int walkDogs(int hour)
{
    int available = company.numAvailableDogs(hour);
    int numToWalk;

    if (available <= maxDogs)
    {
        numToWalk = available;
    }
    else
    {
        numToWalk = maxDogs;
    }

    company.updateDogs(hour, numToWalk);
    return numToWalk;
}

Why Each Piece Matters

  • available <= maxDogs, not < — if the available count is exactly maxDogs, the walker can still take all of them; the cap only kicks in when there are strictly more dogs than the walker can handle.
  • Calling updateDogs with numToWalk, not available — the company only needs to know how many dogs this walker is claiming, which might be fewer than the total available if the walker's capacity is the limiting factor.
  • updateDogs is called before return — the side effect on the company has to happen regardless of the return value, since other dog walkers depend on it being accurate.

Common Mistakes to Avoid

  • Calling updateDogs with the wrong value (e.g., always with available, ignoring the walker's own cap) — this would let a company's dogs get double-claimed by other walkers.
  • Forgetting to call updateDogs at all. The problem explicitly requires using it "appropriately" to receive full credit, since it's the only way other dog walkers avoid signing up for the same dogs.

Part (b): Writing dogWalkShift(int startHour, int endHour)

The Rule, Broken Down

  1. For every hour from startHour to endHour, inclusive, walk dogs during that hour.
  2. Base pay is $5 per dog actually walked that hour.
  3. On top of the base pay, add a $3 bonus for that hour if either of these is true: the walker walked their full maxDogs capacity, or the hour falls between 9 and 17, inclusive.
  4. Total the pay across every hour in the shift.

Step-by-Step Approach

  1. Start a running total at 0.
  2. Loop hour from startHour to endHour, inclusive.
  3. Each hour, call walkDogs(hour) to find out how many dogs were walked, and compute the base pay from that.
  4. Check the two bonus conditions; if either is true, add the $3 bonus for that hour.
  5. Add that hour's pay to the running total.
  6. After the loop, return the total.

The Code

public int dogWalkShift(int startHour, int endHour)
{
    int total = 0;

    for (int hour = startHour; hour <= endHour; hour++)
    {
        int dogsWalked = walkDogs(hour);
        int pay = dogsWalked * 5;

        if (dogsWalked == maxDogs || (hour >= 9 && hour <= 17))
        {
            pay = pay + 3;
        }

        total = total + pay;
    }

    return total;
}

Why Each Piece Matters

  • hour <= endHour, not < — the shift runs "inclusive" of endHour, so that final hour has to be included in the loop, not stopped short of it.
  • Calling walkDogs(hour) instead of reimplementing its logic — the problem requires using it "appropriately" for full credit, and it's also the only way this method's pay calculation reflects the actual capped number of dogs walked, not just whatever the company had available.
  • The || between the two bonus conditions — either one alone is enough to earn the bonus; they don't both need to be true.
  • Parenthesizing (hour >= 9 && hour <= 17) — this groups the two-sided range check together before combining it with ||, so the bonus rule reads exactly as "walked the max, OR fell in the peak window."

Tracing the Example

Using the question's own table, walking hours 7 through 10 with maxDogs = 3:

Hour Dogs walked Base pay Bonus? Total for hour
7 3 15 yes (walked max) 18
8 2 10 no 10
9 2 10 yes (peak hour) 13
10 3 15 yes (walked max) 18

Sum: 18 + 10 + 13 + 18 = 59 — matches the question's total exactly.

Common Mistakes to Avoid

  • Using < instead of <= for the loop bound, which would skip paying for endHour entirely.
  • Combining the bonus conditions with && instead of ||. Only one of the two needs to hold — requiring both would under-award bonuses whenever a walker hits their max outside the 9–17 window (or vice versa).
  • Checking the bonus condition against available dogs instead of dogsWalked. The "walked maxDogs dogs" condition is about what this walker actually did, which walkDogs already correctly caps.
  • Recomputing numAvailableDogs/updateDogs directly here instead of calling walkDogs — this duplicates part (a)'s logic and risks getting the capping rule wrong a second time.

Notes: A Method Not on the AP CSA Quick Reference Sheet

Math.min would collapse part (a)'s if/else into one line, if your class has covered it:

int numToWalk = Math.min(available, maxDogs);

Math.min isn't listed on the AP Quick Reference sheet — but that doesn't make it off-limits. AP CSA graders accept any correct Java. The only real tradeoff is not being able to look its exact behavior up on the reference sheet if you second-guess yourself mid-exam, the way you could with a plain if/else.

Key Takeaways

  • Capping a value at a maximum without Math.min is a two-branch if/else: use the raw value when it already fits, use the cap when it doesn't.
  • Once a method is written and trusted, a later method that builds on it should call it directly — both to satisfy "must use X appropriately" grading requirements and to avoid duplicating (and possibly breaking) its logic.
  • A bonus or discount that applies "if any of several conditions hold" is a straightforward || chain — only reach for && when all of the conditions genuinely need to be true together.

Related FRQs