Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <string>
- // Mr. Liu, with all due respect sir I cannot take you seriously as a
- // programmer nor a lover of computer science when you blatantly
- // disregard ISO 8601 and willingly use the horrific and mangled MM DD
- // YYYY format. Not only does this fly in the face of good morals and
- // common sense and give headaches to those trying to sort through
- // timestamped files, it is a regressive thing to do and you should
- // feel absolutely ashamed. I beg of you to no longer follow the path
- // of nitwits. Turn towards the righteous path of international
- // standards, easy date sorting. Join us in using YYYY-MM-DD formats
- // and the world shall live together in unity forever. MM DD YYYY: Bad
- // for your health, bad for your code, BAD FOR AMERICA.
- void menuPrint(); // Printing the menu in main() is ugly & cluttered.
- bool checkDate(int year=1900, int month=1, int day=1);
- bool leapYear(int year);
- std::string zodiac(int year);
- std::string dayOfWeek(int year, int month, int day);
- std::vector<int> sols(int year, int month, int day);
- int squareByValue(int val);
- int squareByReference(int & ref);
- int squareByPointer(int * ptr);
- int main()
- {
- std::string userChoice;
- while (true)
- {
- menuPrint();
- std::cin >> userChoice;
- if ((userChoice == "q") || (userChoice == "-1"))
- { // User wants to quit; exit program.
- break;
- }
- else if (userChoice == "1")
- { // User chose the leap year program
- int year = 0;
- std::cout << std::endl << "Leap Year:" << std::endl;
- while (!checkDate(year))
- { // Ensure they only enter a valid year.
- std::cout << "Please enter a year 1900 or later." << std::endl;
- std::cin >> year;
- // Every time we read from cin into an integer we will run
- // these two statements, because otherwise the code will
- // freak out if the user enters a string. clear turns off the
- // error flag and ignore jumps to the next newline so that
- // the program does not try to read any more letters into
- // numbers.
- std::cin.clear(); std::cin.ignore(100000,'\n');
- }
- std::cout << year << " is " << (leapYear(year) ? "" : "not ");
- std::cout << "a leap year." << std::endl;
- }
- else if (userChoice == "2")
- { // User chose the zodiac program
- int year = 0;
- std::cout << "Zodiac:" << std::endl;
- while (!checkDate(year))
- { // Ensure they only enter a valid year.
- std::cout << "Please enter a year 1900 or later." << std::endl;
- std::cin >> year;
- std::cin.clear(); std::cin.ignore(100000, '\n');
- }
- std::cout << year << " is the year of the " << zodiac(year) << std::endl;
- }
- else if (userChoice == "3")
- { // user chose the day of the week program.
- std::cout << "Day of the Week:" << std::endl;
- int year = 0;
- int month = 0;
- int day = 0;
- while(!checkDate(year, month, day))
- {
- std::cout << "Please enter a date 1900-01-01 or later. ";
- std::cout << "Use MM DD YYYY format." << std::endl;
- std::cout << "Month:" << std::endl;
- std::cin >> month;
- std::cin.clear(); std::cin.ignore(100000, '\n');
- std::cout << "Day:" << std::endl;
- std::cin >> day;
- std::cin.clear(); std::cin.ignore(100000, '\n');
- std::cout << "Year:" << std::endl;
- std::cin >> year;
- std::cin.clear(); std::cin.ignore(100000, '\n');
- }
- std::cout << year << "-" << month << "-" << day << " falls on a ";
- std::cout << dayOfWeek(year, month, day) << std::endl;
- }
- else if (userChoice == "4")
- { // User chose the Martian Calendar program.
- std::cout << "Martian Calendar:" << std::endl;
- int year = 0;
- int month = 0;
- int day = 0;
- while(!checkDate(year, month, day))
- {
- std::cout << "Please enter a date on or after 1900-1-1. Please ";
- std::cout << " use MM DD YYYY format." << std::endl << "Month:\n";
- std::cin >> month;
- std::cin.clear(); std::cin.ignore(100000, '\n');
- std::cout << "Day:\n";
- std::cin >> day;
- std::cin.clear(); std::cin.ignore(100000, '\n');
- std::cout << "Year:\n";
- std::cin >> year;
- std::cin.clear(); std::cin.ignore(100000, '\n');
- }
- std::vector<int> marsDate = sols(year, month, day);
- std::cout << "The martian date is " << marsDate.at(1) << " ";
- std::cout << marsDate.at(2) << " " << marsDate.at(0) << std::endl;
- }
- else
- {
- std::cout << "\n\nFIXME\n\n";
- }
- }
- return 0;
- }
- void menuPrint()
- {
- std::cout << std::endl;
- std::cout << "Main Menu — Enter an item's menu-number or input q or -1 to ";
- std::cout << "exit the program" << std::endl;
- std::cout << "1) Leap years" << std::endl;
- std::cout << "2) Zodiac" << std::endl;
- std::cout << "3) Day of the week" << std::endl;
- std::cout << "4) Martian Calendar" << std::endl;
- std::cout << "5) Square (by value)" << std::endl;
- std::cout << "6) Square (by reference)" << std::endl;
- std::cout << "7) Square (by pointer)" << std::endl;
- }
- bool checkDate(int year, int month, int day)
- { /* Returns true if the date is valid. Defaults to 1900-01-01 so you
- can check just a year without checking a month or a day. */
- bool validYear = (year >= 1900);
- bool validMonth = ((month >= 1) && (month <= 12));
- int monthMax;
- switch (month)
- {
- case 2:
- monthMax = (leapYear(year) ? 29 : 28);
- break;
- case 4:
- case 6:
- case 9:
- case 11:
- monthMax = 30;
- break;
- default:
- monthMax = 31;
- break;
- }
- bool validDay = ((day >= 1) && (day <= monthMax));
- return (validYear && validMonth && validDay);
- }
- bool leapYear(int year)
- {
- if (year % 4 != 0) // year is not a 4th year
- {
- return false;
- } // any years past this point are divisible by 4
- else if (year % 100 != 0) // year is a 4th year and is not divisible by 100)
- {
- return true; // all such years are leap years.
- } // any years past this point are divisble by 4 and divisble by 100
- else if (year % 400 != 0) // year is divisible by 4 and not divisible by 400
- {
- return false;
- } // any year past here must be divisible by 4 and divisible by 400
- else
- {
- return true; // all such ears are leap years
- }
- }
- std::string zodiac(int year)
- {
- int nthYear = (year - 1900) % 12; // reduce years to 12-yr cycle starting at 1900
- switch (nthYear)
- {
- case 0:
- return "rat";
- case 1:
- return "ox";
- case 2:
- return "tiger";
- case 3:
- return "rabbit";
- case 4:
- return "dragon";
- case 5:
- return "snake";
- case 6:
- return "horse";
- case 7:
- return "goat";
- case 8:
- return "monkey";
- case 9:
- return "rooster";
- case 10:
- return "dog";
- case 11:
- return "pig";
- default:
- return "unknown";
- }
- }
- std::string dayOfWeek(int year, int month, int day)
- { /* Wow okay this is complicated. Basically there's 4 possible
- centries in the gregorian calendar, and they keep cycling over
- and over. Let's call one of these a maj (for major
- centuries). You can either have a century beginning with a common
- year that starts on a monday, such as 1900, a century that starts
- with a leap year that starts on a saturday (such as 2000), a
- century that begins on a common year and starts on a friday (such
- as 2100), or a century that begins with a common year and starts
- on a wednesday, such as 2200. Using this knowledge, we can just
- compute how many monday-saturday cycles have happened since the
- start of the century and then find the day of the week based on
- what day of the week the century started on. */
- // find the number of days in february
- int feb = leapYear(year) ? 29 : 28;
- //find how many days have passed BEFORE the month you're on.
- int months[] = {0,31,feb,31,30,31,30,31,31,30,31,30,31};
- int pastMon = 0;
- for(int i=0; i < month; i++) {pastMon += months[i];}
- // now we're calculating what we called a maj earlier.
- int maj = ((year - 1900) % 400) / 100;
- // get the last two digits of the year since this is all we care about now.
- year %= 100;
- // For calculating total # of days in the years leading up to this one.
- int n = year - 1;
- // Finding that total number of days and storing it in pastYrs.
- int pastYrs = (n>-1) ? ((n-(n/4))*365 + (n/4)*366 + (maj==1 ? 366 : 365)) : 0;
- // Add up the number of days before this month in this year, the number of days
- // in the years leading up to now, and the number of days since the start of
- // the month, and subtract 1 so that the first day is 0.
- int julian = pastYrs + pastMon + day - 1;
- // mod it by 7 to find our "naive" day of the week where every century starts on
- // a monday
- int septCycle = julian % 7;
- // from our naive day septCycle, shift it over by what the century ACTUALLY
- // started on to find the actual day of the week.
- int start;
- switch(maj)
- {
- case 0:
- start = 0;
- break;
- case 1:
- start = 5;
- break;
- case 2:
- start = 4;
- break;
- case 3:
- start = 2;
- break;
- default:
- start = -1000;
- break;
- }
- int dOW = (septCycle + start) % 7;
- // FINALLY return "monday" if it's 0, "tuesday" if it's 1, etc.
- switch(dOW)
- {
- case 0:
- return "monday";
- case 1:
- return "tuesday";
- case 2:
- return "wednesday";
- case 3:
- return "thursday";
- case 4:
- return "friday";
- case 5:
- return "saturday";
- case 6:
- return "sunday";
- default:
- return "unknown";
- }
- }
- std::vector<int> sols(int year, int month, int day)
- { // You know what? The approach I took in the Days of the Week
- // function was too damned mathy. Lets try something a bit more loopy
- // here instead.
- // cumDays adds up the ammount of days in the preceeding months
- std::vector<int> leapYrDays = {0,31,60,91,121,152,182,212,243,274,304,335,366};
- std::vector<int> commYrDays = {0,31,59,90,120,151,181,211,242,273,303,334,365};
- std::vector<int> cumDays = leapYear(year) ? leapYrDays : commYrDays;
- int yrsDays = 0;
- for (int i=1900; i < year; i++)
- {
- yrsDays += leapYear(i) ? 366 : 365;
- }
- int totalDays = yrsDays + cumDays.at(month-1) + day;
- // Total number of martian days since 1900-01-01 mars time.
- int toMartian = totalDays / 1.027;
- int marsYear = toMartian / 672 + 1900;
- int marsMonth = (toMartian - (toMartian / 672 * 672)) / 56 + 1;
- int marsDay = (toMartian - ((marsYear-1900)*672) - ((marsMonth-1)*56));
- return { marsYear, marsMonth, marsDay };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement