using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
int Answer = 0;
for (int Year = 2006; Year <= 2015; Year++) {
for (int Month = 1; Month <= 12; Month++) {
int[,] CalendarArr = DeriveCalendarArr(Year, Month);
int MaxMenseki = DeriveMaxMenseki(CalendarArr);
Answer += MaxMenseki;
}
}
Console.WriteLine("120ヶ月分の面積の和={0}", Answer);
}
//年と月を引数として、カレンダーの2次元配列を返す
static int[,] DeriveCalendarArr(int pYear, int pMonth)
{
//DayOfWeekの値の対応表
// 0 1 2 3 4 5 6
//日 月 火 水 木 金 土
var YokoArrList = new List<int[]>();
var YokoList = new List<int>();
DateTime CurrDay = new DateTime(pYear, pMonth, 1);
//1日の曜日を求める
int CurrYoubi = (int)CurrDay.DayOfWeek;
//1日より前は-1とする
for (int I = 0; I < CurrYoubi; I++) {
YokoList.Add(-1);
}
while (true) {
if (CurrDay.Month != pMonth) { //対象月でない場合
YokoList.Add(-1);
}
else if (CurrYoubi == 0 || CurrYoubi == 6) { //土日の場合
YokoList.Add(-1);
}
else if (IsSyukujitu(CurrDay)) { //祝日の場合
YokoList.Add(-1);
}
else YokoList.Add(CurrDay.Day);
CurrDay = CurrDay.AddDays(1);
CurrYoubi = (int)CurrDay.DayOfWeek;
if (CurrYoubi == 0) {
YokoArrList.Add(YokoList.ToArray());
YokoList.Clear();
if (CurrDay.Month != pMonth) break;
}
}
int[,] WillReturn = new int[7, YokoArrList.Count];
for (int Y = 0; Y <= YokoArrList.Count - 1; Y++) {
for (int X = 0; X <= 6; X++) {
WillReturn[X, Y] = YokoArrList[Y][X];
}
}
return WillReturn;
}
//祝日かを返す
static bool IsSyukujitu(DateTime pDate)
{
string[] StrArr =
{"2006/01/01","2006/01/02","2006/01/09","2006/02/11","2006/03/21","2006/04/29",
"2006/05/03","2006/05/04","2006/05/05","2006/07/17","2006/09/18","2006/09/23",
"2006/10/09","2006/11/03","2006/11/23","2006/12/23","2007/01/01","2007/01/08",
"2007/02/11","2007/02/12","2007/03/21","2007/04/29","2007/04/30","2007/05/03",
"2007/05/04","2007/05/05","2007/07/16","2007/09/17","2007/09/23","2007/09/24",
"2007/10/08","2007/11/03","2007/11/23","2007/12/23","2007/12/24","2008/01/01",
"2008/01/14","2008/02/11","2008/03/20","2008/04/29","2008/05/03","2008/05/04",
"2008/05/05","2008/05/06","2008/07/21","2008/09/15","2008/09/23","2008/10/13",
"2008/11/03","2008/11/23","2008/11/24","2008/12/23","2009/01/01","2009/01/12",
"2009/02/11","2009/03/20","2009/04/29","2009/05/03","2009/05/04","2009/05/05",
"2009/05/06","2009/07/20","2009/09/21","2009/09/22","2009/09/23","2009/10/12",
"2009/11/03","2009/11/23","2009/12/23","2010/01/01","2010/01/11","2010/02/11",
"2010/03/21","2010/03/22","2010/04/29","2010/05/03","2010/05/04","2010/05/05",
"2010/07/19","2010/09/20","2010/09/23","2010/10/11","2010/11/03","2010/11/23",
"2010/12/23","2011/01/01","2011/01/10","2011/02/11","2011/03/21","2011/04/29",
"2011/05/03","2011/05/04","2011/05/05","2011/07/18","2011/09/19","2011/09/23",
"2011/10/10","2011/11/03","2011/11/23","2011/12/23","2012/01/01","2012/01/02",
"2012/01/09","2012/02/11","2012/03/20","2012/04/29","2012/04/30","2012/05/03",
"2012/05/04","2012/05/05","2012/07/16","2012/09/17","2012/09/22","2012/10/08",
"2012/11/03","2012/11/23","2012/12/23","2012/12/24","2013/01/01","2013/01/14",
"2013/02/11","2013/03/20","2013/04/29","2013/05/03","2013/05/04","2013/05/05",
"2013/05/06","2013/07/15","2013/09/16","2013/09/23","2013/10/14","2013/11/03",
"2013/11/04","2013/11/23","2013/12/23","2014/01/01","2014/01/13","2014/02/11",
"2014/03/21","2014/04/29","2014/05/03","2014/05/04","2014/05/05","2014/05/06",
"2014/07/21","2014/09/15","2014/09/23","2014/10/13","2014/11/03","2014/11/23",
"2014/11/24","2014/12/23","2015/01/01","2015/01/12","2015/02/11","2015/03/21",
"2015/04/29","2015/05/03","2015/05/04","2015/05/05","2015/05/06","2015/07/20",
"2015/09/21","2015/09/22","2015/09/23","2015/10/12","2015/11/03","2015/11/23",
"2015/12/23"};
foreach (string EachStr in StrArr) {
string[] wkStrArr = EachStr.Split('/');
DateTime wkDate = new DateTime(
int.Parse(wkStrArr[0]), int.Parse(wkStrArr[1]), int.Parse(wkStrArr[2]));
if (wkDate == pDate) return true;
}
return false;
}
static void DebugPrint(int[,] pCalendarArr)
{
for (int Y = 0; Y <= pCalendarArr.GetUpperBound(1); Y++) {
for (int X = 0; X <= pCalendarArr.GetUpperBound(0); X++) {
Console.Write("{0,2},", pCalendarArr[X, Y]);
}
Console.WriteLine();
}
}
//カレンダーの2次元配列を引数として、最大の長方形の面積を返す
static int DeriveMaxMenseki(int[,] pCalendarArr)
{
int UB_X = pCalendarArr.GetUpperBound(0);
int UB_Y = pCalendarArr.GetUpperBound(1);
int MaxMenseki = 0;
//始点のX座標のループ
for (int StaX = 0; StaX <= UB_X; StaX++) {
//始点のY座標のループ
for (int StaY = 0; StaY <= UB_Y; StaY++) {
if (pCalendarArr[StaX, StaY] == -1) continue;
//横幅のループ
for (int HabaX = 1; StaX + (HabaX - 1) <= UB_X; HabaX++) {
//縦幅のループ
for (int HabaY = 1; StaY + (HabaY - 1) <= UB_Y; HabaY++) {
if (IsTyouhoukei(pCalendarArr, StaX, StaY, HabaX, HabaY) == false) {
break;
}
int Menseki = HabaX * HabaY;
if (MaxMenseki < Menseki) MaxMenseki = Menseki;
}
}
}
}
return MaxMenseki;
}
//長方形かを判定
static bool IsTyouhoukei(int[,] pCalendarArr, int pStaX, int pStaY, int pHabaX, int pHabaY)
{
for (int X = pStaX; X <= pStaX + pHabaX - 1; X++) {
for (int Y = pStaY; Y <= pStaY + pHabaY - 1; Y++) {
if (pCalendarArr[X, Y] == -1) return false;
}
}
return true;
}
}