このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文について、おおまかに説明する。
進捗インジケータの動きを制御するプログラムをシミュレーションする。インジケータは4つの状態(文字)を取る、1つの文字列からなる。文字は|、-、\、/からなる。プログラムでは文字列の出力命令は<instr%gt; <secs>という形式で与えられる。instrは4つの取り得る動き、secsはその動きの継続時間を表している。動きは1秒間に1つである。4つの取り得る動きとは次のことを指す。
- L:左にスピンする。|は\、\は-、-は/、/は|に状態が変化する。
- R:右にスピンする。\は|、|は/、/は-、-は\に状態が変化する。
- S:そのままで状態は変化しない。
- F:バーは90度回転する。\は/、/は\、-は|、|は-になる。
つまり、"F03L02"という文字列と初期状態-が与えらえると、"-|-|\-"という文字列が返されることになる。
startStateという初期状態とprogramというプログラムが与えられたときに、その結果生成される文字列を返せ。文字列のi番目の文字はi秒後の状態を表すことになる。すなわち0秒(開始時点)は、初期状態(startState)に一致する。programは3*k(kは整数)の文字数からなる。3文字ごとに見ると、instrが1文字、secsが2文字になっている。secsは2桁になるよう0埋めされることがある。startStateは4つの状態のいずれかである。
私の解答はこちら。
public class IndicatorMotion {
public String getMotion(String program, char startState) {
StringBuffer sb = new StringBuffer();
String indicator = "|\\-/";
int pos = 0;
for( int i=0 ; i<indicator.length() ; i++ ){
if( startState == indicator.charAt(i) ){
pos = i;
break;
}
}
sb.append(startState);
for( int i=0 ; i<program.length()/3 ; i++ ){
String dir = program.substring(i*3, (i+1)*3);
char instr = dir.charAt(0);
int secs = Integer.parseInt(dir.substring(1));
int nMove = add(instr);
for( int j=0 ; j<secs ; j++ ){
pos = (pos+nMove)%(indicator.length()); // (1)
sb.append(indicator.charAt(pos));
}
}
return sb.toString();
}
private int add(char c){
if( c == 'L' ){
return 1;
}else if( c == 'R' ){
return 3; // -1としたら上の(1)はpos+nMove+indicator.lengthになる
}else if( c == 'S' ){
return 0;
}else{
return 2;
}
}
}得点は163.50/250、中央値は約123点。4つのinstrの位置関係を表すのがポイントかと思います。コードだけでなく、ときには紙も利用するのが良いのでしょう。

0 件のコメント:
コメントを投稿