Java, the number of readings on Sundays, which fell on the 1st day of the month from 1901 to 2000

I am new to programming and Java, and I am trying to teach myself by working through the Project Euler website. I am trying to accomplish this problem: http://projecteuler.net/problem=19 , which:

How many Sundays fell in the first month of the month during the twentieth century (January 1, 1901 to December 31, 2000)?

The way I decided to solve it was to create a 2D array representing the calender and pass it through the counter to 7, and then every time I count to 7, add 1 to this point in the array, At the end I I will sum the first line of the array, and it should be how many Sundays were in the first month.

But I have problems with my cycles, my score to 7 is reset when it reaches the end of the month, and I can’t understand how to stop it from doing this?

Here is my code:

public class Problem019 {
    public static void main (String[] args){

        //System.out.println(LeapYearTest(1996));
        int ThirtyOne = 31;
        int Thirty = 30;
        int FebNorm = 28;
        int FebLeap = 29;
        int a, b, c, Day, e = 0, f = 0;
        int Calander[] []= new int [12] [] ;

        Calander[0] = new int [ThirtyOne];
        Calander[1] = new int [FebNorm];
        Calander[2] = new int [ThirtyOne];
        Calander[3] = new int [Thirty];
        Calander[4] = new int [ThirtyOne];
        Calander[5] = new int [Thirty];
        Calander[6] = new int [ThirtyOne];
        Calander[7] = new int [ThirtyOne];
        Calander[8] = new int [Thirty];
        Calander[9] = new int [ThirtyOne];
        Calander[10] = new int [Thirty];
        Calander[11] = new int [ThirtyOne];

        for (a=1901;a<2001;a++){
            //System.out.println(a);
            if (LeapYearTest(a))
            {
                Calander[1] = new int [FebLeap];
            }
            else
            {
                Calander[1] = new int [FebNorm];
            }

            for (e=0;e<Calander.length;e++)
            {   
                System.out.println("e: " + e);
                f=0;

                while (f<Calander[e].length)
                {   

                    //System.out.println(Calander[e].length);
                    Day=1;
                    while (Day<8 && f<Calander[e].length)
                    {   
                        System.out.println("f: " + f + "\tDay: " + Day + "\tCalander[e][f]: " + Calander[e][f]);
                        Day++;
                        f++;

                        if (f<Calander[e].length && f!=0 && Day==7)
                        {
                        Calander[e][f]+= 1;
                        }

                    }

                }
            }
            //System.out.println(a);
        }
        for (b=0;b<Calander.length;b++)
        {   
            System.out.print(Calander[0][b]);
        }
    }   


    public static boolean LeapYearTest(int x)
    {
        if (x%4==0 || x%400==0){
            return true;
        }
        if (x%100==0){
            return false;
        }
        else return false;
    }

}

This is what it prints, e is the month, f is the days of the month, and day is 7:

f: 25   Day: 5  Calander[e][f]: 0
f: 26   Day: 6  Calander[e][f]: 0
f: 27   Day: 7  Calander[e][f]: 100
f: 28   Day: 1  Calander[e][f]: 0
f: 29   Day: 2  Calander[e][f]: 0
**f: 30 Day: 3  Calander[e][f]: 0**
e: 10
**f: 0  Day: 1  Calander[e][f]: 0**
f: 1    Day: 2  Calander[e][f]: 0
f: 2    Day: 3  Calander[e][f]: 0

How to configure loops so that the Day is not reset at the end of the month? Or is there another way to solve this problem, which does not include so many nested loops?

Thankyou!

+5
source share
8 answers

, . , , Project Euler, , . , , " , , - , , , .

, , ...

Day, 1. :

Day=1;

:

if (Day > 7) {
    Day = 1;
}

, .

. . 29. , calendar[month].length, .

, , - , , . Feb, ( ). , , ( - ). , Java , , .

while .

LeapYearTest true , 100 ( , 100, 4, if, , 100).

( , ).

, ,

1 1900 .

, 1 1901.

(, ) . , , (%) ( ).

public class Problem019 {
    public static void main (String[] args){

        final int ThirtyOne = 31;
        final int Thirty = 30;
        final int FebNorm = 28;
        final int FebLeap = 29;
        int numOfSundays = 0;

        int calendar[][]= new int [12][];

        calendar[0] = new int [ThirtyOne];
        calendar[1] = new int [FebLeap];
        calendar[2] = new int [ThirtyOne];
        calendar[3] = new int [Thirty];
        calendar[4] = new int [ThirtyOne];
        calendar[5] = new int [Thirty];
        calendar[6] = new int [ThirtyOne];
        calendar[7] = new int [ThirtyOne];
        calendar[8] = new int [Thirty];
        calendar[9] = new int [ThirtyOne];
        calendar[10] = new int [Thirty];
        calendar[11] = new int [ThirtyOne];

        int dayOfWeek = 1;
        for (int year = 1900; year < 2001; year++) {
            for (int month = 0; month < calendar.length; month++) {   
                int dayOfMonth=0;

                int daysInMonth;
                if (month == 1) {
                    daysInMonth = isLeapYear(year) ? FebLeap : FebNorm;
                }
                else {
                    daysInMonth = calendar[month].length;
                }

                while (dayOfWeek < 8 && dayOfMonth < daysInMonth) {   
                    System.out.println("year: " + year + "\tday: " + dayOfWeek
                            + "\tcalendar["+month+"]["+dayOfMonth+"]: " + calendar[month][dayOfMonth]);

                    if (dayOfWeek == 7 && year > 1900) {
                        calendar[month][dayOfMonth]++;

                        if (dayOfMonth == 0) {
                            numOfSundays++;
                        }
                    }

                    dayOfMonth++;

                    dayOfWeek++;
                    if (dayOfWeek > 7) {
                        dayOfWeek=1;
                    }
                }
            }
        }

        for (int month = 0; month < calendar.length; month++) {   
            System.out.println(calendar[month][0]);
        }

        System.out.println(numOfSundays);
    }   

    public static boolean isLeapYear(int year){
        if (year % 400 == 0) {
            return true;
        }
        else if (year % 100 == 0) {
            return false;
        }
        else if (year % 4 == 0){
            return true;
        }
        else {
            return false;
        }
    }
}

, . , Java API API, , , , , , Doomsday Algorithm. , java.util.Calendar.

, Doomsday Algorithm, , . , isSunday(MAR,1,year) == (! isLeapYear(year)) && isSunday(FEB,1,year).

+3

, 1901 2001 , , Jan → Dec, , ?

100 * 12 , 10 , .

: .

: , , , .

:

Calendar calendar = Calendar.getInstance();
int count = 0;
for(int i=1901;i<2000;i++){
    for(int j=1;i<12;j++){
        calendar.set(Calendar.YEAR, i);
        calendar.set(Calendar.MONTH,j);
        calendar.set(Calendar.DAY,1);
        if(calendar.get(Calendar.DAY_OF_WEEK).equals(Calendar.SUNDAY)){
            count++;
        }
    }
}

System.out.println();

+4

. , , .

import java.util.Date;
import java.util.GregorianCalendar;

public class SundayOfXX {

    public static void main(String [] argv) {
        int counter = 0;
        for (int year = 1901, last_year = 2000; year <= last_year ; year++) {
            for (int month = 1, last_month = 12; month <= last_month ; month++) {
                Date d = new GregorianCalendar(year,month-1,1).getTime(); // GregorianCalendar use 0 for January
                if (d.getDay() == 0) { // sunday is day number 0
                    counter++;
                    System.out.println(String.valueOf(counter) + " " + d);
                }
            }
        }
        System.out.println("Total sunday in XX century: "+counter);
    }
}

. 171 , 1- ​​ 20- .

+1

:

import java.util.Calendar;
public class Problem019 {   

    public static void main (String[] args){

        Calendar calendar = Calendar.getInstance();
        int countFirstSunday = 0;
        for(int year = 1901; year <= 2000 ; year++) {
            for(int month = 0; month <= 11; month++) {
                calendar.set(year, month, 1);
                if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
                    countFirstSunday++;
                }
            }
        }
        System.out.println("Sundays as the first of month: " + countFirstSunday);
    }

}
+1

:

public static void main(String[] args) {
  final int thirtyOne = 31, thirty = 30;
  final int calendar[][] = new int[12][];
  final int[] febLeap = new int[29];
  final int[] febNorm = new int[28];
  calendar[0] = new int[thirtyOne];
  calendar[2] = new int[thirtyOne];
  calendar[3] = new int[thirty];
  calendar[4] = new int[thirtyOne];
  calendar[5] = new int[thirty];
  calendar[6] = new int[thirtyOne];
  calendar[7] = new int[thirtyOne];
  calendar[8] = new int[thirty];
  calendar[9] = new int[thirtyOne];
  calendar[10] = new int[thirty];
  calendar[11] = new int[thirtyOne];
  int dow = 0; // set to day of week for Jan 1 1901
  for (int y = 1901; y < 2001; y++) {
    calendar[1] = leapYearTest(y)? febLeap : febNorm;
    for (int m = 0; m < calendar.length; m++)
      for (int d = 0; d < calendar[m].length; d++)
        if (dow++ % 7 == 0) calendar[m][d]++;
  }
  int sumSundays = calendar[0][0] + febLeap[0] + febNorm[0];
  for (int i = 2; i < calendar.length; i++) sumSundays += calendar[i][0];
  System.out.println("Number of Sundays is " + sumSundays);
}

public static boolean leapYearTest(int x) {
  if (x % 4 == 0 || x % 400 == 0)
    return true;
  return x % 100 != 0;
}

, , :

public static void main(String[] args) {
  final int[] mLens = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  int dow = 0; // initialize to day of week on Jan 1, 1901
  int suns = 0;
  for (int y = 1901; y < 2001; y++)
    for (int m = 0; m < mLens.length; m++) {
      if (dow++ % 7 == 0) suns++;
      final int mLen = mLens[m] + leapAdd(y, m);
      for (int d = 1; d < mLen; d++) dow++;
    }
  System.out.println(suns);
}

static int leapAdd(int y, int m) {
  if (m != 1) return 0;
  if (y % 4 == 0 || y % 400 == 0) return 1;
  return y % 100 == 0 ? 0 : 1;
}

, , , 7.

    for (int m = 0; m < mLens.length; m++) {
      if (dow == 0) suns++;
      final int mLen = mLens[m] + leapAdd(y, m);
      dow = (dow + mLen) % 7;
    }
0

():

class MyDate { ... } // support adding a number of days and comparing with another MyDate
MyDate end = new MyDate(31. Dec 2000)
MyDate start = new MyDate(first sunday in 20th century)
int count = start.mday == 1 ? 1 : 0;
start.add(7);
while (start < end) (
    if (start.mday == 1) count++;
    start.add(7);
}

, , 2d . ( , , MyDate, .)

0

:

1) Calendar - , - 135

import java.util.Calendar;

public class P19 {

    public static void main(String[] args) {
        int result = 0;
        for ( int year = 1901 ; year <= 2000 ; year++ ) {
            for ( int month = Calendar.JANUARY ; month <= Calendar.DECEMBER ; month++ ) {
                Calendar c = getCalendar(year, month, 1);
                if ( c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ) {
                    result++;
                }
            }
        }
        System.out.println(result);
    }

    private static Calendar getCalendar(int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month);
        c.set(Calendar.DAY_OF_MONTH, day);      // or Calendar.DATE
        return c;
    }

}

:

  • DAY_OF_MONTH DATE .
  • I used Calendar.JANUARYbecause the first month 0, not 1even if the first day / date 1.

2) . - 1.65 ms required :

>
public class P19 {

    public static void main(String[] args) {
        // 1 Jan 1900 - Monday
        // 1900 is not leap => it has 365 days
        // 365 % 7 = 1 => 1 Jan 1901 - Tuesday => 6 Jan 1901 - Sunday

        int yearStart = 1901, yearEnd = 2000;
        int monthStart = 1, monthEnd = 12;
        int dayStart = 6, dayEnd = 31;
        Date dateStart = new Date(yearStart, monthStart, dayStart);
        Date dateStop = new Date(yearEnd, monthEnd, dayEnd);

        int result = 0;
        while (Date.compareDates(dateStart, dateStop) < 0) {
            if (dateStart.day == 1) {
                result++;
            }
            dateStart.addDays(7);
        }
        System.out.println(result);
    }

}

class Date {
    int year;
    int month;
    int day;

    Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public void addDays(int days) {
        int numberOfDaysForMonth = getTotalMonthDays(month, year);
        day += days;
        if (day >= numberOfDaysForMonth) {
            day -= numberOfDaysForMonth;
            month++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }

    }

    public static int compareDates(Date d1, Date d2) {
        if (d1.year == d2.year && d1.month == d2.month && d1.day == d2.day) {
            return 0;
        }
        if (d1.year < d2.year) {
            return -1;
        }
        if (d1.year == d2.year && d1.month < d2.month) {
            return -1;
        }
        if (d1.year == d2.year && d1.month == d2.month && d1.day < d2.day) {
            return -1;
        }
        return 1;
    }

    private int getTotalMonthDays(int m, int y) {
        if (m == 2 && isLeapYear(y)) {
            return 29;
        }
        if (m == 2) {
            return 28;
        }
        if (m == 4 || m == 6 || m == 9 || m == 11) {
            return 30;
        }
        return 31;
    }

    private boolean isLeapYear(int y) {
        if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) {
            return true;
        }
        return false;
    }

}

This implementation is repeated only on Sundays ( addDays(7)).

Some possible improvements:

  • increase the step (for example, for 1, we can add 28instead 7without skipping any day)
  • change the comparison method to return a booleanand simplify its body
0
source
public class CountingSundays {

    public static void main(String[] args) {

        int lastDayOfPreviousMonth = 6; //31 Dec 1899 is Sunday as 1 Jan 1900 is Monday

        int countOfSundayOnFirstOfMonth = 0;

        for (int year = 1900; year <= 2000; year++) {
            for (int month = 1; month <= 12; month++) {
                int dayOnFirstOfThisMonth = (lastDayOfPreviousMonth + 1) % 7;
                if (year > 1900 && dayOnFirstOfThisMonth == 6)
                    countOfSundayOnFirstOfMonth++;
                switch (month) {
                case 1: // Jan
                case 3: // Mar
                case 5: // May
                case 7: // Jul
                case 8: // Aug
                case 10: // Oct
                case 12: // Dec
                    lastDayOfPreviousMonth = (lastDayOfPreviousMonth + 3) % 7;
                    break;
                case 4: // Apr
                case 6: // Jun
                case 9: // Sep
                case 11: // Nov
                    lastDayOfPreviousMonth = (lastDayOfPreviousMonth + 2) % 7;
                    break;
                case 2: // Feb
                    if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
                        lastDayOfPreviousMonth = (lastDayOfPreviousMonth + 1) % 7;
                }
            }
        }


        System.out.println(countOfSundayOnFirstOfMonth);
    }

}
0
source

All Articles