clairec icon

old shitty lab

clairec | PRO | 09/11/16 04:40:29 AM UTC | 0 ⭐ | 510 👁️ | Never ⏰ | []
C++ |

10.31 KB

|

None

|

0 👍

/

0 👎

#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 };
}

Comments