頭の体操

応募はもちろんしてないけど、天下一プログラマーのやつをやってみた。
サクッとjavascriptで。所要時間は多分30〜40分くらい。
問い3だけ時間がかかりすぎるので、まともに実行すらしてない。
問い2の答えは81じゃないの?

var DT = function(y,m,d ) { this.year = y||0; this.month = m||0; this.day=d||0; };
DT.prototype.MAX_MONTH = 12;
DT.prototype.dayOfMonths = [31,28,31,30,31,30,31,31,30,31,30,31];
DT.prototype.leapYearDayOfMonths = [31,29,31,30,31,30,31,31,30,31,30,31];
DT.prototype._leap_cache = {};
DT.prototype.isLeapYear = function() {
	var year = this.year;
	if (typeof this._leap_cache[year] != 'undefined') return this._leap_cache[year];
	var ret = false;
	if (year % 4==0) {
		if (year % 400 == 0) {
			ret = true;
		} else if (year % 100 == 0) {
			ret = false;
		} else {
			ret = true;
		}
	}
	this._leap_cache[year] = ret;
	return ret;
};
DT.prototype.getDayOfMonth = function(){
	var mon = this.month -1;
	if (this.isLeapYear()) return this.leapYearDayOfMonths[mon];
	return this.dayOfMonths[mon];
};
DT.prototype.addDay = function(add_day){
	var day = this.day + add_day;
	var end_day = this.getDayOfMonth();
	if (day > end_day) {
		this.day = day - end_day;
		this.month++;
		if (this.month > this.MAX_MONTH) {
			this.year++;
			this.month = 1;
		}
	} else {
		this.day = day;
	}
};
DT.prototype.cmp = function(lt_dt) {
	if ((this.year > lt_dt.year)
		|| (this.year == lt_dt.year && this.month > lt_dt.month) 
		|| (this.year == lt_dt.year && this.month == lt_dt.month && this.day > lt_dt.day)) {
		return 1;
	} else if (this.year == lt_dt.year && this.month == lt_dt.month && this.day == lt_dt.day) {
		return 0;
	}
	return -1;
};

// main routine
var start = new DT(2001, 1, 1);
var end = new DT(3000, 12, 31);
var start_dow = 1;	// == monday

var cnt = 0;

var add_day = 7 - start_dow;
start.addDay(add_day);
cnt++;

while(true) {
	if (start.cmp(end)>0) {
		cnt--;
		break;
	}
	start.addDay(7);
	cnt++;
}
alert(cnt);
var str = "87104101110321051103211610410132991111171141151013211110232104117109971103210111810111011611544321051163298101991111091011153211010199101115115971141213210211111432111110101321121011111121081013211611132100105115115111108118101321161041013211211110810511610599971083298971101001153211910410599104321049711810132991111101101019911610110032116104101109321191051161043297110111116104101114443297110100321161113297115115117109101329710911111010332116104101321121111191011141153211110232116104101321019711411610444321161041013211510111297114971161013297110100321011131179710832115116971161051111103211611132119104105991043211610410132108971191153278971161171141013297110100327897116117114101115327111110032101110116105116108101321161041011094432973210010199101110116321141011151121019911632116111321161041013211111210511010511111011532111102321099711010710511010032114101113117105114101115321161049711632116104101121321151041111171081003210010199108971141013211610410132999711711510111532119104105991043210510911210110832116104101109321161113211610410132115101112971149711610511111046";
var cnt_h = {};
var cnt = 0;
for (var i=0,l=str.length-4; i<l ; i++) {
	var val = new Number(str.substr(i,4));
	if ( val != 0 && (val % 3) == 0) {
		cnt++;
		cnt_h[val] = true;
	}
}
var unique_cnt = 0;
//var list=[];
for (var key in cnt_h) {
	unique_cnt++;
//	list.push(key);
};
alert([unique_cnt, cnt].join('/'));
//alert(list);
var moneys = [10000,5000,2000,1000,500,100,50,10,5,1];
var TOTAL_PAY = 10000;

function calcPayPattern(rest, index, money_list) {
	var total = 0;
	var pay_v = money_list[index];
	if (rest < 0 || index >= money_list.length) return 0;
	if (rest == 0) return 1;
	if (pay_v == 1) return 1;
	
	var max_pay = Math.floor(rest/pay_v);
	for (var i=max_pay; i >= 0; i--) {
		var cnt = calcPayPattern( rest - i*pay_v, index + 1, money_list);
		if (cnt == 0) break;
		total += cnt;
	}
	return total;
}

var cnt = calcPayPattern(TOTAL_PAY, 0, moneys);

alert(cnt);