この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 件のコメント:
コメントを投稿