2012年6月11日月曜日

TopCoder SRM396 Div2 250Pts

このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文について説明する。

オンライン決済とあるクレジットカード番号の受け付けに関するアプリケーションを作成している。カードの番号は長いので、入力時に間違えやすい。そこで、ユーザによって入力された数字が妥当か確認できるようなメソッドを作成したいと考えている。すべての受付可能なカード番号について、ルーンの公式というものがなりたっている。ルーンの公式とは以下のようなものである。

  1. カード番号を桁ごとに分ける。21378は2 1 3 7 8と分けられる。
  2. もし桁数が偶数であれば、先頭を1とした順番とし、奇数の位置にある桁を2倍する。そうでなければ偶数の位置にある桁を2倍する。上の例では桁数は5で奇数なので、偶数の位置にある数字を2倍することになる。2 1 3 7 8は2 2 3 14 8となる。なお偶数番目というのは2倍する前のものであることに注意(2倍して桁数が2桁になったことは考慮しなくて構わない)。
  3. 各桁の総和を計算する。2桁の数字は1桁ずつに分解して足し算する。これにより、2 2 3 14 8は2+2+3+1+4+8=20になる。
もし上の手続きで得られた数が10で割り切れるのであれば、数字は妥当、そうでなければ妥当でないとなる。クレジットカードの番号を表す文字列cardNumberが与えられたとき、妥当であれば"VALID"、そうでなければ"INVALID"を返すようなメソッドを作成せよ。
public class VerifyCreditCard {

 public String checkDigits(String cardNumber) {
  boolean isEven = cardNumber.length() % 2 == 1 ? true : false; // 元の数字の桁数
  int total = 0; // 3のステップで得られる数字
  for( int i=0 ; i<cardNumber.length() ; i++ ){
   int num = cardNumber.charAt(i) - '0';
   if( isEven && (i+1) % 2 == 0){ // 2倍する数値の条件にマッチしている
    num *= 2;
   }else if( !isEven && i % 2 == 0){
    num *= 2;
   }
   String tmp = "" + num;
   for( int j=0 ; j<tmp.length() ; j++ ){ // 各桁ごとに数値を足し算していく
    total += tmp.charAt(j) - '0';
   }
  }
  if( total % 10 == 0 ){
   return "VALID";
  }else{
   return "INVALID";
  }
 }

}

問題提出先のサーバ再起動で提出時間に5分強の遅延が発生したため、本来の得点は分からずじまい。得点は175.87/250ですが、再起動がなければ205点ぐらいでしょうか。1回のsubmitでシステムテストをクリアしています。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計