项目欧拉#19 - 2少

时间:2017-04-17 01:16:53

标签: java algorithm date

我想问一个人,他/她是否可以帮助我找到我在此问题中失去2个解决方案的错误。我的代码不是很漂亮和可读,但我认为在这里理解逻辑很简单。我坐在这一个小时,甚至制定了不同的解决方案,但在这一个中找不到问题。

private static int _year = 1900;
private static int[] _months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
private static int _month = 0;
private static int _day = 7; //we start from Sunday
private  static int counter = 0;

public static void main(String[] args) {
    while(_year !=1901) 
        nextSunday(_day, _month, _year);

    while(true) {
        if(_year == 2000 && _month == 11 && _day > 31) break;
        nextSunday(_day, _month, _year);
    }
    System.out.println(counter);
}

private static void nextSunday(int day, int month, int year) {
    if(isSundayFirst(_day)) counter++;

    if(year == 2000 && month == 11 && day + 7 > _months[month]) { //to break loop
        _day = day + 7;
    } else if(month == 11 && day + 7 > _months[month]) { // new year, end of month
        _day = day + 7 - _months[month];
        _month = 0;
        _year++;
    } else if(month == 1 && isLeapYear(year) && day + 7 > 29) { // leap year end of february
        _day = day + 7 - 29;
        _month++;
    } else if(month == 1 && !isLeapYear(year) && day + 7 > _months[month]) { // not leap year end of february
        _day = day + 7 - _months[month];
        _month++;
    } else if(day + 7 > _months[month]) { // end of month
        _day = day + 7 - _months[month];
        _month++;
    } else { // next in same month
        _day = day + 7;
    }
}

private static boolean isSundayFirst(int day) {
    return day == 1;
}

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

private static boolean isCentury(int year) {
    return year % 100 == 0;
}

我有169个这样的星期天。我应该再多2​​个。

问题在于:

  

您将获得以下信息,但您可能更愿意这样做   为自己研究。

1 Jan 1900 was a Monday.
Thirty days has September,
April, June and November.
All the rest have thirty-one,
Saving February alone,
Which has twenty-eight, rain or shine.
And on leap years, twenty-nine.
A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
     

在二十世纪的第一个月,有多少个星期天下降了   世纪(1901年1月1日至2000年12月31日)?

我将不胜感激。谢谢。

PS我知道这个_name样式不像Java那样,但我写的很快,无意在任何地方发布它。

1 个答案:

答案 0 :(得分:3)

您的代码存在两个问题,一个导致您超过2而另一个导致您的数量低于4。

  1. 问题#1 这个问题告诉你在1901年开始计算,但你从1900年算起。

    更改

    if(isSundayFirst(_day)) counter++;
    

    if(isSundayFirst(_day) && _year >= 1901) counter++;
    

    解决这个问题。

  2. 问题#2 问题出在这种情况:

    else if(day + 7 > _months[month]) { // end of month
        _day = day + 7 - _months[month];
        _month++;
    }
    

    您已经处理了前两个条件中二月份的情况,因此您需要检查以确保它不是二月。将条件更改为

    else if(month != 1 && day + 7 > _months[month]) 
    

    将解决您的问题。

  3. 旁注:你的nextSunday方法的结构使得解密变得非常困难,所以这是我努力简化它(你现在将在_year > 2000时断开):

    private static void nextSunday(int day, int month, int year) {
        int febNum = isLeapYear(_year) ? 29 : 28;
        int dayCount = (month == 1) ? febNum : _months[_month]; //days in current month
    
        _day += 7;
    
        if (_day > dayCount) {  //new month
            _month++;
            _day -= dayCount;
        } 
        if (_month == 12) {    //new year
            _month = 0;
            _year++;
        }
    }