このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文についておおまかに説明する。
あなたは大みそかをとても楽しみにしている。次の大みそかはそんなに遠くなく、あなたはそれを楽しみにしている。そして、ある日、ある疑問で目が覚めることになる。「待てよ、大みそかはどのぐらい離れているんだ?」
この質問に答えるため、今年がどの程度終わったかを示すプログレスバーという、簡単なアプリケーションを作成することにした。この問題においては、目標はこのアプリケーションのもっとも重要なパートを実装することである。つまり、現在時刻を示すcurrentDateという文字列を受け取ったときに、百分率でその年の進捗状況を返すというものである。currentDateという変数は"Month DD, YYYY HH:MM"という文字列で与えられる。ここで、Monthは月の名前を表し、YYYYは西暦、DD、HH、MMは日、時間、分を二桁の数値で表したものである。なお、0埋めされる可能性がある(訳注:例えば5月の場合MMは05ということになる)。
私の実装はこちら。
public class YearProgressbar {
public double percentage(String currentDate) {
int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 現在時刻の解釈
String[] date = currentDate.split(" ");
int year = Integer.parseInt(date[2]);
int month = monthInt(date[0]);
int day = Integer.parseInt(date[1].substring(0, 2));
int hour = Integer.parseInt(date[3].substring(0, 2));
int minutes = Integer.parseInt(date[3].substring(3));
boolean leap = isLeap(year); // 今年はうるう年か?
int daysInYear = leap ? 366 : 365;
int secondsInYear = daysInYear * 24 * 3600; // 1年間の秒数
int alreadyPassedDays = 0;
for( int i=0 ; ilt;month ; i++ ){
alreadyPassedDays += days[i];
if( leap && i == 1 ) alreadyPassedDays++; // 経過した日数を計算
}
int alreadyPassedSeconds = minutes * 60 + hour * 3600 +
(day - 1 + alreadyPassedDays) * 24 * 3600 ; // 今年の経過秒数を求めている
return alreadyPassedSeconds * 1.0 / secondsInYear * 100;
}
private boolean isLeap(int year){
if( year % 400 == 0 || (year % 4 == 0 && year % 100 != 0) ){
return true;
}
return false;
}
private int monthInt(String month){ // monthという文字列から月の値を返す。失敗すれば-1。
String[] monthString = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
for( int i=0 ; i<monthString.length ; i++ ){
if( month.equals(monthString[i]) ){
return i;
}
}
return -1;
}
}
得点は315.02/500、1回のsubmitでシステムテストクリア。中央値は150点。愚直な実装ではありますが、これで問題なし。分単位までで良かったので、秒単位に変換する必要はありませんでしたね。
0 件のコメント:
コメントを投稿