2009年3月4日水曜日

アッカーマン関数続

インデックスを一つの構造体で管理するようにしてすっきりした。

struct index2D
{
public int m, n;
public override int GetHashCode()
{
return m ^ n;
}
}
static Dictionary<index2D, int> Ack = new Dictionary<index2D, int>();
static int Ackermann(index2D mn)
{
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();
Stack<index2D> arg = new Stack<index2D>();
arg.Clear();
arg.Push(mn);
while (arg.Count > 0) {
index2D index = arg.Peek();
index2D index_;
if (Ack.ContainsKey(index)) {
arg.Pop();
continue;
} else {
int value;
if (index.m == 0) {
value = checked(arg.Peek().n + 1);
} else if (index.n == 0) {
index_.m = index.m - 1;
index_.n = 1;
if (Ack.ContainsKey(index_)) {
value = Ack[index_];
} else {
arg.Push(index_);
continue;
}
} else {
index_.m = index.m;
index_.n = index.n - 1;
int n_;
if (Ack.ContainsKey(index_)) {
n_ = Ack[index_];
} else {
arg.Push(index_);
continue;
}
index_.m = index.m - 1;
index_.n = n_;
if (Ack.ContainsKey(index_)) {
value = Ack[index_];
} else {
arg.Push(index_);
continue;
}
}
Ack[index] = value;
continue;
}
}
watch.Stop();
Console.WriteLine(watch.Elapsed.ToString() + " elapsed.");
return Ack[mn];
}

0 件のコメント: