Like the title says, I'm trying to find out how many times Friday the 13th appears in a given year. I have to use a date
class and somehow write code to figure it out.
Date.h
#ifndef DATE_H
#define DATE_H
#include <string>
#include <iostream>
using namespace std;
string Month[] = { "", "January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December" };
int daysInMonth[2][13] = { { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
string DOW[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "" };
class Date {
private:
int *month;
int *day;
int *year;
public:
// constructors
Date(int month, int day, int year);
Date(); // default constructor
Date(Date &other); // copy constructor
Date(string mmddyyyy); // constructor that takes a string as parameter e.g "10/31/2012"
~Date();
// overload assignment operator
Date & operator=(Date & rhs);
Date & operator++();
Date & operator++(int);
Date & operator--();
Date & operator--(int);
bool operator ==(Date & rhs);
bool operator != (Date & rhs);
bool operator > (Date & rhs);
bool operator < (Date & rhs);
int operator-(Date & rhs);
Date & operator+(int);
// accessors
int getDay() {
return *this->day;
}
int getMonth() {
return *this->month;
}
int getYear() {
return *this->year;
}
static Date toDate(int doy, int yr) {
int dayOfMonth = doy;
int month = 1;
int isleap = isLeap(yr);
for (int i = 1; i < 13; i++) {
int daysThisMonth = daysInMonth[isleap][i];
if (dayOfMonth <= daysThisMonth) {
break;
}
else {
month++;
dayOfMonth -= daysThisMonth;
}
}
return *new Date(month, dayOfMonth, yr);
}
// display date in the format of mm/day/year e.g. 10/31/2012
void display() {
cout << *this->month << "/" << *this->day << "/" << *this->year;
}
// returns true if the given year is a leap year and false otherwise
static int isLeap(int year) {
return ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0));
}
// returns the day code the the new year day of the given year
static int get_day_code(int year) {
return (year + (year - 1) / 4 - (year - 1) / 100
+ (year - 1) / 400) % 7;
}
// overloading get_day_code that returns the day code of the specific day
static int get_day_code(int year, int month, int day) {
int dayCodeForYear = get_day_code(year);
Date temp(month, day, year);
int doy = temp.dayOfYear() - 1;
int dayCode = (dayCodeForYear + doy) % 7;
return dayCode;
}
int dayOfWeek() { // return the day code of this day
int dayOfYear = this->dayOfYear() - 1;
int firstDayOfTheYear = Date::get_day_code(*this->year);
dayOfYear += firstDayOfTheYear;
return dayOfYear % 7;
}
int dayOfYear() { // returns the day of the year, eg, the day of year for Feb 28 is 59.
int doy = 0;
int isleap = isLeap(*year);
for (int i = 1; i < *month; i++) {
doy += daysInMonth[isleap][i];
}
doy += *day;
return doy;
}
};
Date::Date(int month, int day, int year) {
this->month = new int(month);
this->day = new int(day);
this->year = new int(year);
}
Date::Date() {
this->month = new int(1);
this->day = new int(1);
this->year = new int(2000);
}
Date::Date(Date &other) {
this->month = new int(*(other.month));
this->day = new int(*(other.day));
this->year = new int(*(other.year));
}
Date::Date(string mmddyyyy) {
string mm = mmddyyyy.substr(0, 2);
string dd = mmddyyyy.substr(2, 2);
string yyyy = mmddyyyy.substr(4, 4);
this->month = new int(atoi(mm.c_str()));
this->day = new int(atoi(dd.c_str()));
this->year = new int(atoi(yyyy.c_str()));
}
Date::~Date() {
if (month) delete month;
if (day) delete day;
if (year) delete year;
}
bool Date::operator == (Date & rhs) {
return (*year == *(rhs.year) && *month == *(rhs.month) && *day == *(rhs.day));
}
bool Date::operator != (Date & rhs) {
return !(*this == rhs);
}
bool Date::operator > (Date & rhs) {
if (*year > *(rhs.year)) return true;
else if (*year < *(rhs.year)) return false;
else if (*month > *(rhs.month)) return true;
else if (*month < *(rhs.month)) return false;
else if (*day > *(rhs.day)) return true;
return false;
}
bool Date::operator < (Date & rhs) {
if (*year < *(rhs.year)) return true;
else if (*year > *(rhs.year)) return false;
else if (*month < *(rhs.month)) return true;
else if (*month > *(rhs.month)) return false;
else if (*day < *(rhs.day)) return true;
return false;
}
Date & Date::operator=(Date & rhs) {
*this->month = *rhs.month;
*this->day = *rhs.day;
*this->year = *rhs.year;
return *this;
}
Date & Date::operator++() {
Date tmp = *this + 1;
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *this;
}
Date & Date::operator++(int) {
Date tmp = *this + 1;
Date * output = new Date(tmp);
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *output;
}
Date & Date::operator--() {
Date tmp = *this + -1;
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *this;
}
Date & Date::operator--(int) {
Date tmp = *this + -1;
Date * output = new Date(tmp);
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *output;
}
int Date::operator-(Date & rhs) {
int yearsDiff = *this->year - *rhs.year;
int daysDiff = this->dayOfYear() - rhs.dayOfYear();
daysDiff += yearsDiff * 365;
return daysDiff;
}
Date & Date::operator+(int) {
int n = 0;
int doy = dayOfYear();
int newDoy = doy + n;
int yearsDiff = newDoy / 365;
newDoy = newDoy % 365;
int newYear = *this->year + yearsDiff;
Date newDate = Date::toDate(newDoy, newYear);
return *new Date(newDate);
}
#endif
This is the code I've been messing with for a while:
Source.cpp
#include <iostream>
#include <iomanip>
#include "Date.h"
using namespace std;
void iterateMonth(int);
bool isFriday13th();
string dayofweek[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "" };
string month[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" };
//int dayInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//int dayInMonthLeap[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
void iterateMonth(int year) {
int dayCode, month, daysInMonth, day, u;
bool leapYear;
cout << year;
// returns the day on which January 1 of year begins.
dayCode = Date::getDayCode(year);
// returns true if year is a leap year, false otherwise
leapYear = Date::isLeap(year);
// month is 0 for Jan, 1 for Feb, etc.
for (month = 1; month <= 12; month++)
{
switch (month)
{
case 1:
cout << "
January
";
daysInMonth = 31;
break;
case 2:
cout << "
February
";
if (leapYear)
daysInMonth = 29;
else
daysInMonth = 28;
break;
case 3:
cout << "
March
";
daysInMonth = 31;
break;
case 4:
cout << "
April
";
daysInMonth = 30;
break;
case 5:
cout << "
May
";
daysInMonth = 31;
break;
case 6:
cout << "
June
";
daysInMonth = 30;
break;
case 7:
cout << "
July
";
daysInMonth = 31;
break;
case 8:
cout << "
August
";
daysInMonth = 31;
break;
case 9:
cout << "
September
";
daysInMonth = 30;
break;
case 10:
cout << "
October
";
daysInMonth = 31;
break;
case 11:
cout << "
November
";
daysInMonth = 30;
break;
case 12:
cout << "
December
";
daysInMonth = 31;
break;
}
//cout << "
Sun Mon Tue Wed Thu Fri Sat
";
for (int i = 0; i < (sizeof(dayofweek) / sizeof(dayofweek[0])); i++)
{
cout << dayofweek[i] << " ";
}
cout << endl;
for (day = 1; day <= dayCode * 5; day++)
{
cout << " ";
}
for (day = 1; day <= daysInMonth; day++)
{
cout << setw(3) << day;
if ((day + dayCode) % 7 > 0)
{
cout << " ";
}
else
cout << endl;
}
dayCode = (dayCode + daysInMonth) % 7;
}
}
//bool isFriday13th() {
//
//}
int main() {
int year;
//cout << "Please enter a year: ";
cout << "Final ";
cin >> year;
iterateMonth(year);
}
One idea I got from someone was to create a Date
object for January 13th, use the dayOfWeek
method to check if it's Friday, and if not, increment until I reach Friday, then jump ahead 7 and use getDay
to check if it's 13. I tried this out with this:
Date tmp(1, 13, year);
int dc = tmp.dayOfWeek(); // return day code
tmp.display();
cout << endl;
++tmp;
tmp.display();
cout << endl;
I expected the tmp.display();
line to show 1/13/2013 (giving 2013 as the year), which it did, but the ++tmp
line gave the same result. I also thought that I would have to somehow find the day code that corresponds to Friday (right now dc
is 0), but I couldn't figure that out.
Also, another post related to the same problem said that every month that begins in Sunday will have Friday the 13th, so I tried thinking of how to implement that. Maybe somewhere in the first for
loop (above the switch
statement) I could check something like if (firstDay = Sunday) { cout << "Friday13th exists in " << month << endl; }
That's kinda horrible pseudo-code, but it was the idea I had going. Anyone have ideas? Any help would be appreciated, and thank you in advance.
See Question&Answers more detail:
os