Qiiteを眺めていたら、Apexでズンドコキヨシまとめに参加されている方がいらっしゃったので便乗します!
#言語解析的にDFAで
コンパイラを作っていた時の知識が役にたちました。
ズン
とドコ
のトークンによって状態遷移していくDFAを作成する事で、現在の状態の把握と次の状態の取得を簡略化しています。
ちなみに再帰関数バージョンは Tail Recursion になっているので、ループでの実行にした方が良いと思われ。キヨシより先にスタックオーバーフローが来るかも!
ZunDokoKiyoshi.apxc
public class ZunDokoKiyoshi {
public Enum ZDState {Z, ZZ, ZZZ, ZZZZ, ZZZZD}
public static Map<Set<Object>, ZDState> dfa = new Map<Set<Object>, ZDState>{
new Set<Object>{null, 'ズン'} => ZDState.Z,
new Set<Object>{ZDState.Z, 'ズン'} => ZDState.ZZ,
new Set<Object>{ZDState.ZZ, 'ズン'} => ZDState.ZZZ,
new Set<Object>{ZDState.ZZZ, 'ズン'} => ZDState.ZZZZ,
new Set<Object>{ZDState.ZZZZ, 'ドコ'} => ZDState.ZZZZD
};
// 再帰関数バージョン
public static void zundokoRecursion(ZDState state){
if(state == ZDState.ZZZZD){
System.debug('キ・ヨ・シ!');
} else {
String token = Math.random() > 0.5 ? 'ズン' : 'ドコ';
System.debug(token);
zundokoRecursion(dfa.get(new Set<Object>{state, token}));
}
}
// ループバージョン
public static void zundokoLoop(){
for(ZDState state = null; state != ZDState.ZZZZD;){
String token = Math.random() > 0.5 ? 'ズン' : 'ドコ';
System.debug(token);
state = dfa.get(new Set<Object>{state, token});
}
System.debug('キ・ヨ・シ!');
}
}
#実行結果