Probably not a lot of explanation needed as to what this is, and it even works exactly the way I want it to. My real problem is program termination. I've output traced my return values and the nested for loops I'm using in my main function to step through values. I can see no reason for this happening, but it's taking the program about 10 extra minutes after the last pass through my loops to actually terminate. Although my loop indices are incrementing (because of the precheck), my Ackermann function is evidently not executing an extra iteration (not that I'd want it to anyway). On the other hand, the only logical explanation is that the loop is not breaking, but if that were the case, my Ackermann function should return a new b value. So the only other cause I can think of for this is that it's taking the garbage collection that long to clear my data structures and flush the memory heap. For those not familiar, the idea here is to implement what is traditionally presented as an ultra cumbersome recursive function as an iterative function. Recursively:
Given positive integers m and n: If m = 0, return n + 1; Else If n = 0, return Ackermann(m - 1, 1); Else return Ackermann(m - 1, Ackermann(m, n - 1)). So iteratively, the idea is to use a stack to emulate the recursive function calls so that you can use memory from the heap and you're not dependent on the call stack size, which limits your execution time. I fear I'm overlooking something in my flow that's causing these long delays between the time the computations finish, and the time my program reaches the point where the user makes a clean exit.
Here's my code:
static void Main(string[] args)
{
ulong i, j;
i = j = 0;
for (i = 1; i <= 3; i++)
for (j = 1; j <= 15; j++)
Console.WriteLine("[{0}] Ackermann({1},{2}) = {3}", DateTime.Now, i, j, Ackermann(i, j));
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
static ulong Ackermann(ulong a, ulong b)
{
Stack<ulong> ackStack = new Stack<ulong>();
ackStack.Push(a);
while (ackStack.Count > 0)
{
a = ackStack.Pop();
if (a == 0)
b++;
else if (b == 0)
{
ackStack.Push(--a);
b = 1;
}
else
{
ackStack.Push(--a);
ackStack.Push(++a);
b--;
}
}
return b;
}
Thoughts? Side note, this is c#, but this behavior also occurs in C++ compiled with MinGW.