Sprint View

2019 FRQ 1

9 min read

2019 AP CSA FRQ 1: APCalendar

The APCalendar class contains methods used to calculate information about a calendar. You will write two methods of the class.

Your Mission: Complete both parts to earn up to 9 points (5 for Part A, 4 for Part B). Your score will be saved locally so you can track your progress!

Your Progress: 0/9 points | Best Time: --:-- | Attempts: 0

public class APCalendar
{
    /** Returns true if year is a leap year and false otherwise. */
    private static boolean isLeapYear(int year)
    { /* implementation not shown */ }

    /** Returns the number of leap years between year1 and year2, inclusive.
     * Precondition: 0 <= year1 <= year2
     */
    public static int numberOfLeapYears(int year1, int year2)
    { /* to be implemented in part (a) */ }

    /** Returns the value representing the day of the week for the first day of year,
     * where 0 denotes Sunday, 1 denotes Monday, ..., and 6 denotes Saturday.
     */
    private static int firstDayOfYear(int year)
    { /* implementation not shown */ }

    /** Returns n, where month, day, and year specify the nth day of the year.
     * Returns 1 for January 1 (month = 1, day = 1) of any year.
     * Precondition: The date represented by month, day, year is a valid date.
     */
    private static int dayOfYear(int month, int day, int year)
    { /* implementation not shown */ }

    /** Returns the value representing the day of the week for the given date
     * (month, day, year), where 0 denotes Sunday, 1 denotes Monday, ...,
     * and 6 denotes Saturday.
     * Precondition: The date represented by month, day, year is a valid date.
     */
    public static int dayOfWeek(int month, int day, int year)
    { /* to be implemented in part (b) */ }
}


Part (a): numberOfLeapYears

Think About It: A leap year occurs every 4 years, but there are exceptions! Can you figure out the pattern before coding?

Write the static method numberOfLeapYears, which returns the number of leap years between year1 and year2, inclusive. In order to calculate this value, a helper method is provided for you:

  • isLeapYear(year) returns true if year is a leap year and false otherwise

Complete the method numberOfLeapYears below. You must use isLeapYear appropriately to receive full credit.

Quick Knowledge Check (click to expand) Before you code, answer these: 1. What years between 2000-2020 are leap years? 2. How many total leap years is that? 3. What loop structure will you use? Hint: 2000, 2004, 2008, 2012, 2016, 2020 = 6 leap years!

Code Runner Challenge

Part (a) - numberOfLeapYears Solution

View IPYNB Source
// CODE_RUNNER: Part (a) - numberOfLeapYears Solution

public class Main {
    
    private static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    
    public static int numberOfLeapYears(int year1, int year2) {
        int count = 0;
        for (int y = year1; y <= year2; y++) {
            if (isLeapYear(y)) {
                count++;
            }
        }
        return count;
    }
    
    public static void main(String[] args) {
        System.out.println("numberOfLeapYears(2000, 2020) = " + numberOfLeapYears(2000, 2020));
        System.out.println("Expected: 6");
    }
}
APCalendar.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Part (b): dayOfWeek

Real World Connection: This is exactly how your phone’s calendar app figures out what day any date falls on!

Write the static method dayOfWeek, which returns the integer value representing the day of the week for the given date (month, day, year), where 0 denotes Sunday, 1 denotes Monday, …, and 6 denotes Saturday.

For example, 2019 began on a Tuesday, and January 5, 2019, was a Saturday. As a result, firstDayOfYear(2019) returns 2, and dayOfWeek(1, 5, 2019) returns 6.

Two helper methods are provided:

  • firstDayOfYear(year) returns the integer value representing the day of the week for the first day of year
  • dayOfYear(month, day, year) returns n, where month, day, and year specify the nth day of the year

Complete method dayOfWeek below. You must use firstDayOfYear and dayOfYear appropriately to receive full credit.

Walk Through the Logic (click to expand) Let's trace through January 5, 2019: 1. **Jan 1, 2019** was a Tuesday (day 2) 2. **Jan 5** is the **5th day** of the year 3. Starting from Tuesday, count forward: Wed(3), Thu(4), Fri(5), **Sat(6)** 4. Formula: `(startDay + dayOfYear - 1) % 7` Why subtract 1? Because Jan 1 is day 1, not day 0!

Code Runner Challenge

Part (b) - dayOfWeek Solution

View IPYNB Source
// CODE_RUNNER: Part (b) - dayOfWeek Solution

public class Main {
    
    private static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    
    private static int firstDayOfYear(int year) {
        int y = year - 1;
        return (y + y/4 - y/100 + y/400 + 1) % 7;
    }
    
    private static int dayOfYear(int month, int day, int year) {
        int[] daysInMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (isLeapYear(year)) daysInMonth[2] = 29;
        int total = 0;
        for (int m = 1; m < month; m++) total += daysInMonth[m];
        return total + day;
    }
    
    public static int dayOfWeek(int month, int day, int year) {
        int startDay = firstDayOfYear(year);
        int nthDay = dayOfYear(month, day, year);
        return (startDay + nthDay - 1) % 7;
    }
    
    public static void main(String[] args) {
        String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
        int result = dayOfWeek(1, 5, 2019);
        System.out.println("dayOfWeek(1, 5, 2019) = " + result + " (" + days[result] + ")");
        System.out.println("Expected: 6 (Saturday)");
    }
}
APCalendar.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Scoring Guidelines

Part (a) - 5 points

Points Criteria
+1 Initializes and accumulates count in loop
+1 Loops through all years in range (year1 to year2 inclusive)
+1 Calls isLeapYear
+1 Checks if isLeapYear returns true
+1 Returns the count

Part (b) - 4 points

Points Criteria
+1 Calls firstDayOfYear(year)
+1 Calls dayOfYear(month, day, year)
+1 Calculates sum and subtracts 1
+1 Returns result mod 7

Solutions

Part (a) Solution

// Complete Solution for Part (a) - numberOfLeapYears

public class Main {
    
    private static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    
    public static int numberOfLeapYears(int year1, int year2) {
        int count = 0;
        for (int y = year1; y <= year2; y++) {
            if (isLeapYear(y)) {
                count++;
            }
        }
        return count;
    }
    
    public static void main(String[] args) {
        System.out.println("=== Part (a) Solution: numberOfLeapYears ===\n");
        
        // Test case from the problem
        System.out.println("numberOfLeapYears(2000, 2020) = " + numberOfLeapYears(2000, 2020));
        System.out.println("Expected: 6");
        System.out.println();
        
        // Additional test cases
        System.out.println("numberOfLeapYears(2000, 2004) = " + numberOfLeapYears(2000, 2004));
        System.out.println("Expected: 2 (2000 and 2004)");
        System.out.println();
        
        System.out.println("numberOfLeapYears(1900, 1900) = " + numberOfLeapYears(1900, 1900));
        System.out.println("Expected: 0 (1900 is NOT a leap year - divisible by 100 but not 400)");
    }
}
APCalendarPartA.main(null);

Part (b) Solution

// Complete Solution for Part (b) - dayOfWeek

public class Main {
    
    private static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    
    private static int firstDayOfYear(int year) {
        // Returns day of week for Jan 1 of given year (0=Sunday, 1=Monday, etc.)
        int y = year - 1;
        return (y + y/4 - y/100 + y/400 + 1) % 7;
    }
    
    private static int dayOfYear(int month, int day, int year) {
        // Returns which day of the year (1 = Jan 1, 32 = Feb 1, etc.)
        int[] daysInMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (isLeapYear(year)) daysInMonth[2] = 29;
        int total = 0;
        for (int m = 1; m < month; m++) total += daysInMonth[m];
        return total + day;
    }
    
    public static int dayOfWeek(int month, int day, int year) {
        int startDay = firstDayOfYear(year);
        int nthDay = dayOfYear(month, day, year);
        return (startDay + nthDay - 1) % 7;
    }
    
    public static void main(String[] args) {
        String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
        
        System.out.println("=== Part (b) Solution: dayOfWeek ===\n");
        
        // Test case from the problem
        int result1 = dayOfWeek(1, 5, 2019);
        System.out.println("dayOfWeek(1, 5, 2019) = " + result1 + " (" + days[result1] + ")");
        System.out.println("Expected: 6 (Saturday)");
        System.out.println();
        
        // Additional test cases
        int result2 = dayOfWeek(1, 1, 2019);
        System.out.println("dayOfWeek(1, 1, 2019) = " + result2 + " (" + days[result2] + ")");
        System.out.println("Expected: 2 (Tuesday - first day of 2019)");
        System.out.println();
        
        int result3 = dayOfWeek(7, 4, 2019);
        System.out.println("dayOfWeek(7, 4, 2019) = " + result3 + " (" + days[result3] + ")");
        System.out.println("Expected: 4 (Thursday - July 4th, 2019)");
    }
}
APCalendarPartB.main(null);

Hints

Part (a) Hints

  1. You need a counter variable to track leap years
  2. Use a for loop from year1 to year2 (inclusive means use <=)
  3. Call isLeapYear(y) for each year and increment if true

Part (b) Hints

  1. Get what day Jan 1 falls on using firstDayOfYear(year)
  2. Get which day of the year the date is using dayOfYear(month, day, year)
  3. Add them together and subtract 1 (since Jan 1 is day 1, not day 0)
  4. Use % 7 to wrap around the week

Example: For January 5, 2019:

  • firstDayOfYear(2019) = 2 (Tuesday)
  • dayOfYear(1, 5, 2019) = 5
  • Result: (2 + 5 - 1) % 7 = 6 (Saturday) ✓

Self-Assessment & Score Tracker

Use this tool to grade your own solution and track your progress. Be honest - it helps you learn!

Grade Part (a) - numberOfLeapYears (5 points)

Check each box for criteria you met in your solution:






Part (a) Score: 0/5

Grade Part (b) - dayOfWeek (4 points)





Part (b) Score: 0/4



Challenge Yourself!

Already got a perfect score? Try these extensions:

Challenge 1: Optimize numberOfLeapYears

Can you solve Part (a) without using a loop? Think mathematically!

Hint Count leap years from year 0 to year2, then subtract leap years from year 0 to year1-1.

Challenge 2: Day Name Converter

Modify dayOfWeek to return the actual day name (“Sunday”, “Monday”, etc.) instead of a number.

Challenge 3: Find Your Birthday!

Use the methods to figure out what day of the week you were born. Was it a Monday? A Friday?

Challenge 4: Historical Events

Pick a famous historical date and verify what day it fell on:

  • July 4, 1776 (US Independence)
  • July 20, 1969 (Moon Landing)
  • November 9, 1989 (Berlin Wall Falls)

Course Timeline