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