トップページに戻る
次のC#のサンプルへ
前のC#のサンプルへ
8-12 ハノイの塔
問題
ハノイの塔(円盤は3枚)を解きます。
ソース
using System;
using System.Collections.Generic;
class Program
{
struct jyoutaiDef
{
internal int Level;
internal string MoveLog;
internal List<int> Jiku1;
internal List<int> Jiku2;
internal List<int> Jiku3;
internal void init()
{
Jiku1 = new List<int> { 3, 2, 1 };
Jiku2 = new List<int>();
Jiku3 = new List<int>();
MoveLog = string.Empty;
}
internal bool IsGoal()
{
if (Jiku3.Count != 3) return false;
for (int I = 0; I <= 2; I++) {
if (Jiku3[I]+I != 3) return false;
}
return true;
}
internal jyoutaiDef GetClone()
{
jyoutaiDef willReturn;
willReturn.Level = this.Level;
willReturn.MoveLog = (string)this.MoveLog.Clone();
willReturn.Jiku1 = new List<int>();
foreach (int each in this.Jiku1) willReturn.Jiku1.Add(each);
willReturn.Jiku2 = new List<int>();
foreach (int each in this.Jiku2) willReturn.Jiku2.Add(each);
willReturn.Jiku3 = new List<int>();
foreach (int each in this.Jiku3) willReturn.Jiku3.Add(each);
return willReturn;
}
}
static void Main(string[] args)
{
var jyoutai = new jyoutaiDef();
jyoutai.init();
var que = new Queue<jyoutaiDef>();
que.Enqueue(jyoutai);
int answerLevel = int.MaxValue;
int restCnt = 999999;
while (que.Count != 0) {
jyoutai = que.Dequeue();
//Console.WriteLine(jyoutai.MoveLog);
if (--restCnt == 0) {
Console.WriteLine("CountStop!!!");
return;
}
if (++jyoutai.Level > answerLevel) continue;
if (jyoutai.IsGoal()) {
Console.WriteLine("answer");
Console.WriteLine(jyoutai.MoveLog);
answerLevel = jyoutai.Level;
continue;
}
//軸1から移動
if (jyoutai.Jiku1.Count > 0) {
int moveVal = jyoutai.Jiku1[jyoutai.Jiku1.Count - 1];
if (jyoutai.Jiku2.Count == 0
|| jyoutai.Jiku2[jyoutai.Jiku2.Count - 1] > moveVal) {
jyoutaiDef saved = jyoutai.GetClone();
saved.Jiku2.Add(moveVal);
saved.Jiku1.Remove(moveVal);
saved.MoveLog += "Level" + saved.Level.ToString() + "円盤" + moveVal.ToString() + "を軸1から軸2へ";
saved.MoveLog += Environment.NewLine;
que.Enqueue(saved);
}
if (jyoutai.Jiku3.Count == 0
|| jyoutai.Jiku3[jyoutai.Jiku3.Count - 1] > moveVal) {
jyoutaiDef saved = jyoutai.GetClone();
saved.Jiku3.Add(moveVal);
saved.Jiku1.Remove(moveVal);
saved.MoveLog += "Level" + saved.Level.ToString() + "円盤" + moveVal.ToString() + "を軸1から軸3へ";
saved.MoveLog += Environment.NewLine;
que.Enqueue(saved);
}
}
//軸2から移動
if (jyoutai.Jiku2.Count > 0) {
int moveVal = jyoutai.Jiku2[jyoutai.Jiku2.Count - 1];
if (jyoutai.Jiku1.Count == 0
|| jyoutai.Jiku1[jyoutai.Jiku1.Count - 1] > moveVal) {
jyoutaiDef saved = jyoutai.GetClone();
saved.Jiku1.Add(moveVal);
saved.Jiku2.Remove(moveVal);
saved.MoveLog += "Level" + saved.Level.ToString() + "円盤" + moveVal.ToString() + "を軸2から軸1へ";
saved.MoveLog += Environment.NewLine;
que.Enqueue(saved);
}
if (jyoutai.Jiku3.Count == 0
|| jyoutai.Jiku3[jyoutai.Jiku3.Count - 1] > moveVal) {
jyoutaiDef saved = jyoutai.GetClone();
saved.Jiku3.Add(moveVal);
saved.Jiku2.Remove(moveVal);
saved.MoveLog += "Level" + saved.Level.ToString() + "円盤" + moveVal.ToString() + "を軸2から軸3へ";
saved.MoveLog += Environment.NewLine;
que.Enqueue(saved);
}
}
//軸3から移動
if (jyoutai.Jiku3.Count > 0) {
int moveVal = jyoutai.Jiku3[jyoutai.Jiku3.Count - 1];
if (jyoutai.Jiku1.Count == 0
|| jyoutai.Jiku1[jyoutai.Jiku1.Count - 1] > moveVal) {
jyoutaiDef saved = jyoutai.GetClone();
saved.Jiku1.Add(moveVal);
saved.Jiku3.Remove(moveVal);
saved.MoveLog += "Level" + saved.Level.ToString() + "円盤" + moveVal.ToString() + "を軸3から軸1へ";
saved.MoveLog += Environment.NewLine;
que.Enqueue(saved);
}
if (jyoutai.Jiku2.Count == 0
|| jyoutai.Jiku2[jyoutai.Jiku2.Count - 1] > moveVal) {
jyoutaiDef saved = jyoutai.GetClone();
saved.Jiku2.Add(moveVal);
saved.Jiku3.Remove(moveVal);
saved.MoveLog += "Level" + saved.Level.ToString() + "円盤" + moveVal.ToString() + "を軸3から軸2へ";
saved.MoveLog += Environment.NewLine;
que.Enqueue(saved);
}
}
}
}
}
実行結果
answer
Level1円盤1を軸1から軸3へ
Level2円盤2を軸1から軸2へ
Level3円盤1を軸3から軸2へ
Level4円盤3を軸1から軸3へ
Level5円盤1を軸2から軸1へ
Level6円盤2を軸2から軸3へ
Level7円盤1を軸1から軸3へ
解説
Queueジェネリックは強力ですねぇ