Теория чисел модульной арифметики как учесть корректировки
Я не уверен, является ли мое решение оправданным (ответ 171) - Project Euler Q.19, поскольку мне трудно разобраться в модульной арифметике, и я не совсем уверен, был ли мой подход к нему правильным или нет... Я возникли проблемы при попытке получить эквивалентность наличия 0 в качестве ключа, а не 1 в понедельник для ссылки в хэш-таблице. Вопрос был;
- 1 января 1900 года был понедельник.
- Тридцать дней сентябрь, апрель, июнь и ноябрь. У всех остальных тридцать один, спасительный февраль, в котором двадцать восемь, дождь
или сиять. И в високосные годы двадцать девять.- Високосный год встречается в любой год, равномерно делимый на 4, но не на столетие, если он не делится на 400.
Сколько воскресений выпало на первое число месяца в течение двадцатого века (с 1 января 1901 года по 31 декабря 2000 года)?
Поэтому я начал с суммы дней, равной 1 (ссылка на дни в хэш-таблице), и вычел 1 после нахождения суммы воскресных чисел, поскольку выполнение этого значения на 0 приводило к проблемам, когда общая сумма дней делилась на 3 и 6 (3: среда, 6: воскресенье). Как я мог сделать это, используя 0 в качестве ссылки на понедельник?
import java.util.*;
public class p19 {
public static void main(String[] args) {
Hashtable<Integer, String> days = new Hashtable<Integer, String>();
days.put(1, "Monday");
days.put(2, "Tuesday");
days.put(3, "Wednesday");
days.put(4, "Thursday");
days.put(5, "Friday");
days.put(6, "Saturday");
days.put(7, "Sunday");
Hashtable<Integer, String> months = new Hashtable<Integer, String>();
months.put(1, "January");
months.put(2, "February");
months.put(3, "March");
months.put(4, "April");
months.put(5, "May");
months.put(6, "June");
months.put(7, "July");
months.put(8, "August");
months.put(9, "September");
months.put(10, "October");
months.put(11, "November");
months.put(12, "December");
int min, max;
min = 1900;
max = 2000;
String[][] arr = new String[12 * (max - min + 1)][];
// Total days starts at 1 to make modular arithmetic easier when accounting for days
// (i.e., 1 Monday, 2 Tuesday, etc.) and since the first day, hence, 0th day on 1 Jan 1900 is Monday.
for (int year = min, index = 0, totalDays = 1; year <= max; year++) {
for (int month = 1; month <= 12; month++, index++) {
arr[index] = new String[numberOfDays(month,year)];
int sum = 1;
System.out.println(months.get(new Integer(month)) + " " + year);
for (int day = 1; day <= numberOfDays(month, year); day++, totalDays++) {
if (totalDays % 7 == 0) {
arr[index][day - 1] = days.get(new Integer((totalDays % 7 + 7) % 365));
}
else {
arr[index][day - 1] = days.get(new Integer((totalDays % 7) % 365));
}
if (sum > 7) {
System.out.println();
sum = 1;
}
System.out.print(totalDays + ":= " + arr[index][day - 1] + ", " + day + " | ");
sum++;
}
System.out.println("\n");
}
}
int count = 0;
for (int i = 1; i < arr.length; i++) {
if (arr[i][0] == "Sunday") {
count++;
}
}
// Subtract 1 from count since the total days were overstated by 1 before inititallizing array
System.out.println("Number of Sundays that fell on the first of the month from: 1/Jan/1901 - 31/Dec/2000: " + (count - 1));
}
public static int numberOfDays (int month, int year) {
int days = 0;
switch (month) {
case 7:
case 4:
case 6:
case 11:
days = 30;
break;
case 2:
if (isLeapYear(year)) {
days = 29;
}
else {
days = 28;
}
break;
default: days = 31;
break;
}
return days;
}
public static boolean isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
}
1 ответ
Ваша проверка daysInMonth неверна - результат должен быть правильным по заболеваемости:
switch (month) {
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
Остальная часть программы может быть упрощена - обратите внимание, что начальный год также должен быть исправлен, dow означает DayOfWeek:
public static void main (String[] args) {
int count = 0;
// dow = 2, since 1.1.1901 was a Thuesday (2)
for (int year = 1901, dow = 2; year <= 2000; ++year)
{
for (int month = 1; month <= 12; ++month)
{
if (dow == 0) {
// System.out.println ("Date: " + year + "-" + month);
++count;
}
dow = (dow + numberOfDays (month, year)) % 7;
}
}
System.out.println ("Number of Sundays that fell on the first of the month from: 1/Jan/1901 - 31/Dec/2000: " + count);
}