このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文についておおまかに説明する。
カード1には1~8の整数、カード2には1~4、9~12の整数、カード3には1、2、5、6、9、10、13、14、カード4には1~15の奇数が書かれている。太郎は花子に対して、1~16の整数を1つ思い浮かべ、それが各カードに含まれているか否かを尋ねた。その答えで整数は唯一に定まる。引数のanswerという文字列にはYないしNという文字が入り、カードiに数字が含まれているか否かの回答はi番目の文字に対応しているものとする(Yなら含まれる、Nなら含まれない)。このとき、花子が想像している数字を返すメソッドを作成せよ。
import java.util.ArrayList;
public class NumberMagicEasy {
public int theNumber(String answer) {
int[][] numbers = {{1, 2, 3, 4, 5, 6, 7, 8},
{1, 2, 3, 4, 9, 10, 11, 12},
{1, 2, 5, 6, 9, 10, 13, 14},
{1, 3, 5, 7, 9, 11, 13, 15}
};
int[] pts = new int[16];
if( answer.indexOf("Y") == -1 ) return 16; // 全部Nなら16
for( int i=0 ; i<answer.length() ; i++ ){
if( answer.charAt(i) == 'Y' ){
for( int j=0 ; j<numbers[i].length ; j++ ){
pts[numbers[i][j]-1] += 1;
}
}else{
ArrayList<Integer> al = new ArrayList();
for( int j=1 ; j<16 ; j++ ){
al.add(j);
}
for( int j=0 ; j<numbers[i].length ; j++ ){
if( al.contains(numbers[i][j]) ){
int idx = al.indexOf(numbers[i][j]);
al.remove(idx);
}
}
for( int j=0 ; j<al.size() ; j++ ){
pts[al.get(j)-1]++;
}
al.clear();
}
}
for( int i=0 ; i<pts.length ; i++ ){ // 全部の条件にマッチする数字を返す
if( pts[i] == numbers.length ) return i+1;
}
return 16;
}
}
得点は117.24/250、1回のsubmitでシステムテストクリア。削除の仕様に対する設計がちょっと面倒でした。方針としては、各質問の回答で条件に合う数字に1点、合わない数字は0点をつけて、4回の質問で4点(=全部の条件に合う)になったものが答えになるように実装しました。