読者です 読者をやめる 読者になる 読者になる

個人的自由ノート

ふと自分が気になった事を書いてます

C++で問題を解く

てっきり後2問で終わりだと思っていたのですが、まだ後5問ぐらい残ってましたね・・・。甘く見てました・・・。

#ifndef q13_1
#define q13_1

class Id {
private:
  static int counter;
  int no;
  mutable int called;
  static int called_total;
public:
  Id();
  int id() const;
  static int get_max_id();
  int id_called() const { return called; }
  static int id_called_total();
};

#endif



#include "q13_1.h"

using namespace std;

int Id::counter = 0;
int Id::called_total = 0;

Id::Id() : no(++counter), called(0) {

}

Id::id() const {
  called++;
  called_total++;
  return no;
}

int Id::get_max_id() {
  return counter;
}

int Id::id_called_total() {
  return called_total;
}
#ifndef q13_2
#define q13_2

#include <string>
#include <iostream>

class Date {
  int y;
  int m;
  int d;

  static int dmax[];
  static int days_of_year(int y);
  static int days_of_month(int y, int m);

  static int adjusted_month(int m);
  static int adjusted_day(int y, int m, int d);

public:
  Date();
  Date(int yy, int mm = 1, int dd = 1);

  static bool leap_year(int year) {
    return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
  }

  int year() const { return y; }
  int month() const { return m; }
  int day() const { return d; }

  void set_year(int yy);
  void set_month(int mm);
  void set_day(int dd);

  void set(int yy, int mm, int dd);

  bool leap_year() const { return leap_year(y); }

  Date preceding_day() const;
  Date following_day() const;

  int day_of_year() const;
  int day_of_week() const;

  std::string to_string() const;

  Date& operator++();
  Date operator++(int);

  Date& operator--();
  Date operator--(int);

  Date& operator+=(int dn);
  Date& operator-=(int dn);

  Date operator+(int dn) const;
  friend Date operator+(int dn, const Date& date);

  Date operator-(int dn) const;

  long operator-(const Date& day) const;

  bool operator==(const Date& day) const;
  bool operator!=(const Date& day) const;

  bool operator>(const Date& day) const;
  bool operator>=(const Date& day) const;
  bool operator<(const Date& day) const;
  bool operator<=(const Date& day) const;
};

std::ostream& operator<<(std::ostream& s, const Date& x);
std::istream& operator>>(std::istream& s, Date& x);

#endif


#include <ctime>
#include <sstream>
#include <iostream>
#include "q13_2.h"

using namespace std;

int Date::dmax[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int Date::days_of_month(int y, int m) {
  return dmax[m - 1] + (m == 2 && leap_year(y));
}

int Date::days_of_year(int year) {
  return 365 + leap_year(year);
}

int Date::adjusted_month(int m) {
  return m < 1 ? 1 : m > 12 ? 12 : m;
}

int Date::adjusted_day(int y, int m, int d) {
  if(d < 1)
    return 1;
  int max_day = days_of_month(y, m);
  return d > max_day ? max_day : d;
}

Date::Date() {
  time_t current = time(NULL);
  struct tm *local = localtime(&current);

  y = local->tm_year + 1900;
  m = local->tm_mon + 1;
  d = local->tm_mday;
}

Date::Date(int yy, int mm, int dd) {
  set(yy, mm, dd);
}

void Date::set_year(int yy) {
  y = yy;
  d = adjusted_day(y, m, d);
}

void Date::set_month(int mm) {
  m = adjusted_month(mm);
  d = adjusted_day(y, m, d);
}

void Date::set_day(int dd) {
  d = adjusted_day(y, m, dd);
}

void Date::set(int yy, int mm, int dd) {
  y = yy;
  m = adjusted_month(mm);
  d = adjusted_day(y, m, dd);
}

Date Date::preceding_day() const {
  Date temp(*this);
  return --temp;
}

Date Date::following_day() const {
  Date temp(*this);
  return ++temp;
}

int Date::day_of_year() const {
  int days = d;

  for(int i = 1; i < m; i++)
    days += days_of_month(y, i);
  return days;
}

int Date::day_of_week() const {
  int yy = y;
  int mm = m;
  if(mm == 1 || mm == 2) {
    yy--;
    mm += 12;
  }
  return (yy + yy / 4 - yy / 100 + yy / 400 + (13 * mm + 8) / 5 + d) % 7;
}

string Date::to_string() const {
  ostringstream s;
  s << y << "年" << m << "月" << d << "日";
  return s.str();
}

Date& Date::operator++() {
  if(d < days_of_month(y, m))
    d++;
  else {
    if(++m > 12) {
      y++;
      m = 1;
    }
    d = 1;
  }
  return *this;
}

Date Date::operator++(int) {
  Date temp(*this);
  ++(*this);
  return temp;
}

Date& Date::operator--() {
  if(d > 1)
    d--;
  else {
    if(--m <= 1) {
      y--;
      m = 12;
    }
    d = days_of_month(y, m);
  }
  return *this;
}

Date Date::operator--(int) {
  Date temp(*this);
  --(*this);
  return temp;
}

Date& Date::operator+=(int dn) {
  if(dn < 0)
    return *this -= -dn;

  d += dn;

  while(d > days_of_month(y, m)) {
    d -= days_of_month(y, m);
    if(++m > 12) {
      y++;
      m = 1;
    }
  }

  return *this;
}

Date& Date::operator-=(int dn) {
  if(dn < 0)
    return *this += -dn;

  d -= dn;

  while(d < 1) {
    if(--m < 1) {
      y--;
      m = 12;
    }
    d += days_of_month(y, m);
  }

  return *this;
}

Date Date::operator+(int dn) const {
  Date temp(*this);
  return temp += dn;
}

Date operator+(int dn, const Date& day) {
  return day + dn;
}

Date Date::operator-(int dn) const {
  Date temp(*this);
  return temp -= dn;
}

long Date::operator-(const Date& day) const {
  long count;
  long count1 = this->day_of_year();
  long count2 = day.day_of_year();

  if(y == day.y)
    count = count1 - count2;
  else if(y > day.y) {
    count = days_of_year(day.y) - count2 + count1;
    for(int yy = day.y + 1; yy < y; yy++)
      count += days_of_year(yy);
  } else {
    count = -(days_of_year(y) - count1 + count2);
    for(int yy = y + 1; yy < day.y; yy++)
      count -= days_of_year(yy);
  }

  return count;
}

bool Date::operator==(const Date& day) const {
  return y == day.y && m == day.m && d == day.d;
}

bool Date::operator!=(const Date& day) const {
  return !(*this == day);
}

bool Date::operator>(const Date& day) const {
  if(y > day.y) return true;
  if(y < day.y) return false;

  if(m > day.m) return true;
  if(m < day.m) return false;

  return d > day.d;
}

bool Date::operator>=(const Date& day) const {
  return !(*this < day);
}

bool Date::operator<(const Date& day) const {
  if(y < day.y) return true;
  if(y > day.y) return false;

  if(m < day.m) return true;
  if(m > day.m) return false;

  return d < day.d;
}

bool Date::operator<=(const Date& day) const {
  return !(*this > day);
}

ostream& operator<<(ostream& s, const Date& x) {
  return s << x.to_string();
}

istream& operator>>(istream& s, Date& x) {
  int yy, mm, dd;
  char ch;

  s >> yy >> ch >> mm >> ch >> dd;
  x = Date(yy, mm, dd);
  return s;
}