Batman25663
Batman25663

Reputation: 272

Project Euler 19: Counting Sundays, Java

I'm using the Calendar API of Java to calculate the total number of sundays which fall on the first day of every month. The Following code gives me 1 extra days for the specified starting date and ending date of date format (Year/Month/Date). 1900/01/01 to 1910/01/01

Input format of the code is :
1<=Testcases<=10
Starting Date
Ending Date

import java.io.*;
import java.util.*;
import java.time.DayOfWeek;
public class ProjectEuler19 {

public static void main(String[] args) {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
    Scanner scanner = new Scanner(System.in);
    int testCases = scanner.nextInt();
    do{
     int sundays = 0;
     Calendar c = Calendar.getInstance();
     int monthStart,dateStart,monthEnd,dateEnd;
     int yearStart,yearEnd;
     yearStart = scanner.nextInt();
     monthStart = scanner.nextInt();
     dateStart = scanner.nextInt();
     yearEnd = scanner.nextInt();
     monthEnd = scanner.nextInt();
     dateEnd = scanner.nextInt();
     String[] getDayOfWeek = new String[]{
        "MONDAY",
        "TUESDAY",
        "WEDNESDAY",
        "THURSDAY",
        "FRIDAY",
        "SATURDAY",
        "SUNDAY"
     };
        for(int y = yearStart; y<=yearEnd; y++) {
                for(int m = monthStart; m<=12; m++) {
                        c.set(y,m-1,1);
                        if(String.valueOf(getDayOfWeek[c.get(Calendar.DAY_OF_WEEK)-1]).equals(String.valueOf(DayOfWeek.SUNDAY))) {
                            sundays++;
                        }
                        if(m > monthEnd && y == yearEnd)
                            break;
                }
        }
        System.out.println(sundays);
       testCases--;
    }while(testCases != 0 && testCases>=1 && testCases<=100);

  }
}

And the sample out put is :

2
1900 1 1
1910 1 1
17
2000 1 1
2020 1 1
36

According the calendar the number of sundays between 1900 and 1910 are 18 and the number of sundays between 2000 and 2020 are 35.

Upvotes: 2

Views: 746

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79085

java.time

In March 2014, Java 8 introduced the modern, java.time date-time API which supplanted the error-prone legacy, java.util date-time API. Any new code should use the java.time API. If you are receiving an instance of java.util.Date, convert it tojava.time.Instant, using Date#toInstant and derive other date-time classes of java.time from it as per your requirement.

Solution using modern date-time API

  1. LocalDate#getDayOfWeek returns you an enum constant for a given LocalDate. You can use this constant for your comparison.
  2. You do not need nested loops if you use dates in your loop instead of years and months separately. You can move to the next month using LocalDate#plusMonths(1).

Demo:

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.printf(
                "The no. of sundays falling on the first day of the month from 1900-01-01 to 1910-01-01: %d%n",
                sundaysOnFirstDayOfMonth(LocalDate.of(1900, 1, 1), LocalDate.of(1910, 1, 1)));
        System.out.printf(
                "The no. of sundays falling on the first day of the month from 2000-01-01 to 2020-01-01: %d%n",
                sundaysOnFirstDayOfMonth(LocalDate.of(2000, 1, 1), LocalDate.of(2020, 1, 1)));
    }

    static int sundaysOnFirstDayOfMonth(LocalDate startDate, LocalDate endDate) {
        int counter = 0;
        // Move startDate to the 1st day of the next month if its day-of-month is not 1;
        // otherwise, keep it as it is
        startDate = startDate.getDayOfMonth() > 1 ?
                startDate.plusMonths(1).withDayOfMonth(1) :
                startDate;

        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusMonths(1))
            if (date.getDayOfWeek() == DayOfWeek.SUNDAY)
                counter++;

        return counter;
    }
}

Output:

The no. of sundays falling on the first day of the month from 1900-01-01 to 1910-01-01: 18
The no. of sundays falling on the first day of the month from 2000-01-01 to 2020-01-01: 35

Online Demo

Assumptions:

  1. The above code assumes that if the day-of-month of startDate, passed to the function, sundaysOnFirstDayOfMonth is not 1, start counting from the next month. If you require to start counting from the month of startDate, irrespective of its day-of-month, replace startDate = startDate.getDayOfMonth() > 1 ? startDate.plusMonths(1).withDayOfMonth(1) : startDate with startDate = startDate.withDayOfMonth(1).
  2. The above code assumes that endDate is inclusive. If you want to exclude endDate, replace !date.isAfter(endDate) with date.isBefore(endDate).

Learn more about the modern Date-Time API from Trail: Date Time.

Upvotes: 1

Joni
Joni

Reputation: 111259

You are actually counting the number of Mondays. Calendar.SUNDAY is the first week day constant, and has value 1.

Why not compare c.get(Calendar.DAY_OF_WEEK) with Calendar.SUNDAY directly?

Upvotes: 3

Related Questions