トップページに戻る
次のJavaアルゴリズムパズルへ
前のJavaアルゴリズムパズルへ
3-9 川渡り 3匹の狼と小鳥
Javaアルゴリズムパズル
3匹ずつの狼と小鳥を、向こう岸に渡す。
・いかだに乗れるのは2匹まで
・1匹も乗ってないと動かない
・どちらの岸でも狼が小鳥の数より大きくなると、
小鳥が食べられて失敗する
ソース
public final class ookami_kotori{
int maxLevel = 20; //高さ制限
class StackDataDef {
int pHune =0;
int OOkami =3;
int Kotori =3;
int Level = 0;
String Log ="";
}
//スタック
class StackClass {
int stackP;
StackDataDef stackData[];
StackClass(){
stackP = 0;
stackData = new StackDataDef[99999];
}
private void push(StackDataDef pushData){
stackData[stackP] = new StackDataDef();
stackData[stackP].pHune = pushData.pHune;
stackData[stackP].OOkami = pushData.OOkami;
stackData[stackP].Kotori = pushData.Kotori;
stackData[stackP].Level = pushData.Level;
String willWrite ="(";
if (pushData.OOkami == 3) willWrite += "狼3";
if (pushData.OOkami == 2) willWrite += "狼2";
if (pushData.OOkami == 1) willWrite += "狼";
if (pushData.Kotori == 3) willWrite += "鳥3";
if (pushData.Kotori == 2) willWrite += "鳥2";
if (pushData.Kotori == 1) willWrite += "鳥";
if (pushData.pHune == 0) willWrite += "←";
else willWrite += "→";
if (pushData.OOkami == 0) willWrite += "狼3";
if (pushData.OOkami == 1) willWrite += "狼2";
if (pushData.OOkami == 2) willWrite += "狼";
if (pushData.Kotori == 0) willWrite += "鳥3";
if (pushData.Kotori == 1) willWrite += "鳥2";
if (pushData.Kotori == 2) willWrite += "鳥";
willWrite +=")";
stackData[stackP].Log = pushData.Log + willWrite;
stackP++;
}
private StackDataDef pop(){
return stackData[--stackP];
}
boolean isEmpty(){ return stackP == 0; }
}
public static void main(String[] args) {
ookami_kotori mi = new ookami_kotori();
mi.main();
}
void main() {
StackClass st = new StackClass();
StackDataDef willPush = new StackDataDef();
//Start With句
willPush.Level = 1;
willPush.pHune = 1;
willPush.OOkami = 2; willPush.Kotori = 3; st.push(willPush);
willPush.OOkami = 1; willPush.Kotori = 3; st.push(willPush);
willPush.OOkami = 2; willPush.Kotori = 2; st.push(willPush);
int ansCnt=0;
while (st.isEmpty() == false){
StackDataDef priInfo = st.pop();
int queenCnt = 0;
//合格経路なら表示
if (priInfo.OOkami == 0 && priInfo.Kotori == 0){
System.out.println("解" + Integer.toString(++ansCnt));
System.out.println(priInfo.Log);
if (maxLevel > priInfo.Level) maxLevel = priInfo.Level; //高さ制限値を更新
continue;
}
if (++priInfo.Level >=maxLevel) continue; //高さ制限
if (priInfo.pHune ==0){
priInfo.pHune = 1;
if (priInfo.OOkami >= 2){
priInfo.OOkami -=2;
if (isValid(priInfo)) st.push(priInfo);
priInfo.OOkami +=2;
}
if (priInfo.OOkami >= 1){
priInfo.OOkami -=1;
if (isValid(priInfo)) st.push(priInfo);
priInfo.OOkami +=1;
}
if (priInfo.Kotori >= 2){
priInfo.Kotori -=2;
if (isValid(priInfo)) st.push(priInfo);
priInfo.Kotori +=2;
}
if (priInfo.Kotori >= 1){
priInfo.Kotori -=1;
if (isValid(priInfo)) st.push(priInfo);
priInfo.Kotori +=1;
}
if (priInfo.OOkami >= 1 && priInfo.Kotori >= 1){
priInfo.OOkami -=1; priInfo.Kotori -=1;
if (isValid(priInfo)) st.push(priInfo);
priInfo.OOkami +=1; priInfo.Kotori -=1;
}
}
else {
priInfo.pHune = 0;
if (priInfo.OOkami <= 1){
priInfo.OOkami +=2;
if (isValid(priInfo)) st.push(priInfo);
priInfo.OOkami -=2;
}
if (priInfo.OOkami <= 2){
priInfo.OOkami +=1;
if (isValid(priInfo)) st.push(priInfo);
priInfo.OOkami -=1;
}
if (priInfo.Kotori <= 1){
priInfo.Kotori +=2;
if (isValid(priInfo)) st.push(priInfo);
priInfo.Kotori -=2;
}
if (priInfo.Kotori <= 2){
priInfo.Kotori +=1;
if (isValid(priInfo)) st.push(priInfo);
priInfo.Kotori -=1;
}
if (priInfo.OOkami <= 2 && priInfo.Kotori <= 2){
priInfo.OOkami +=1; priInfo.Kotori +=1;
if (isValid(priInfo)) st.push(priInfo);
priInfo.OOkami -=1; priInfo.Kotori -=1;
}
}
}
}
private boolean isValid(StackDataDef StackData){
if (StackData.Kotori != 0 && StackData.Kotori < StackData.OOkami) return false;
if (StackData.Kotori != 3 && (3-StackData.Kotori) < (3-StackData.OOkami)) return false;
return true;
}
}
実行結果
解5
(狼2鳥2→狼鳥)
(狼2鳥3←狼)
(鳥3→狼3)
(狼鳥3←狼2)
(狼鳥→狼2鳥2)
(狼2鳥2←狼鳥)
(狼2→狼鳥3)
(狼3←鳥3)
(狼→狼2鳥3)
(狼鳥←狼2鳥2)
(→狼3鳥3)