Its arguments are never negative and it always terminates. Write a function which returns the value of A(m,n){\displaystyle A(m,n)}. Arbitrary precision is preferred (since the function grows so quickly), but not required.

m equ3; Nr of iterations for the main loop.n equ5; Do NOT set them higher, or it will take hours to complete on; 68k, not to mention that the stack usage will become astronomical.; Perhaps n can be a little higher... If you do increase the ranges; then don't forget to increase the stack size.

\ Memoization is a technique whereby intermediate computed values are stored\ away against later need. It is particularly valuable when calculating those\ values is time or resource intensive, as with the Ackermann function.

The program reads two integers (first m, then n) from command line, idles around funge space, then outputs the result of the Ackerman function.
Since the latter is calculated truly recursively, the execution time becomes unwieldy for most m>3.

Three solutions are presented here.
The first one is a purely recursive version, only using the formulas at the top of the page.
The value of A(4,1) cannot be computed due to stack overflow.
It can compute A(3,9) (4093), but probably not A(3,10)

The second version is a purely non-recursive solution that easily can compute A(4,1).
The program uses a stack for Ackermann function calls that are to be evaluated, but that cannot be computed given the currently known function values - the "known unknowns".
The currently known values are stored in a hash table.
The Hash table also contains incomplete Ackermann function calls, namely those for which the second argument is not known yet - "the unknown unknowns".
These function calls are associated with "known unknowns" that are going to provide the value of the second argument. As soon as such an associated known unknown becomes known, the unknown unknown becomes a known unknown and is pushed onto the stack.

Although all known values are stored in the hash table, the converse is not true: an element in the hash table is either a "known known" or an "unknown unknown" associated with an "known unknown".

Whee. Well, with some extra work, we calculated one more n value, big deal, right?
But see, A(4, 2) = A(3, A(4, 1)) = A(3, 65533) = A(2, A(3, 65532)) = ... you can see how fast it blows up. In fact, no amount of caching will help you calculate large m values; on the machine I use A(4, 2) segfaults because the recursions run out of stack space--not a whole lot I can do about it. At least it runs out of stack space quickly, unlike the first solution...

When invoked, each required A(m,n) needed to solve the requested (solve ?m ?n) facts gets generated as its own fact. Below shows the invocation of the above, as well as an excerpt of the final facts list. Regardless of how many input (solve ?m ?n) requests are made, each possible A(m,n) is only solved once.

note description:"Example of Ackerman function" synopsis:"[ The EIS link below (in Eiffel Studio) will launch in either an in-IDE browser or and external browser (your choice). The protocol informs Eiffel Studio about what program to use to open the `src' reference, which can be URI, PDF, or DOC. See second EIS for more information. ]" EIS:"name=Ackermann_function", "protocol=URI", "tag=rosetta_code","src=http://rosettacode.org/wiki/Ackermann_function" EIS:"name=eis_protocols", "protocol=URI", "tag=eiffel_docs","src=https://docs.eiffel.com/book/eiffelstudio/protocols"

Mixed-language solution using pure FBSL, Dynamic Assembler, and Dynamic C layers of FBSL v3.5 concurrently. The following is a single script; the breaks are caused by switching between RC's different syntax highlighting schemes:

This version works by first generating verbs (functions) and then applying them to compute the rows of the related Buck function; then the Ackermann function is obtained in terms of the Buck function. It uses extended precision to be able to compute 4 Ack 2.

The Ackermann function derived in this fashion is primitive recursive. This is possible because in J (as in some other languages) functions, or representations of them, are first-class values.

refers to the currently executing procedure (closure) and is used when writing recursive procedures. (You could also use the name of the procedure, Ackermann in this case, but then a concurrently executing task or thread could re-assign that name while the recursive procedure is executing, resulting in an incorrect result.)

Ackermann[4,2] has 19729 digits, several thousands of digits omitted in the result above for obvious reasons. Ackermann[5,0] can be computed also quite fast, and is equal to 65533.
Summarizing Ackermann[0,n_], Ackermann[1,n_], Ackermann[2,n_], and Ackermann[3,n_] can all be calculated for n>>1000. Ackermann[4,0], Ackermann[4,1], Ackermann[4,2] and Ackermann[5,0] are only possible now. Maybe in the future we can calculate higher Ackermann numbers efficiently and fast. Although showing the results will always be a problem.

This is the Ackermann function with some (obvious) elements elided. The ack/3 predicate is implemented in terms of the ack/2 function. The ack/2 function is implemented in terms of the ack/3 predicate. This makes the code both more concise and easier to follow than would otherwise be the case. The integer type is used instead of int because the problem statement stipulates the use of bignum integers if possible.

---- Ackermann.exw-- =============---- optimised. still no bignum library, so ack(4,2), which is power(2,65536)-3, which is-- apparently 19729 digits, and any above, are beyond (the CPU/FPU hardware) and this.-- (replaced ack(atom,atom) with ack(int,int) since the former fares no better.)

procedure Ackermann() for i=0 to 3 do for j=0 to 10 do printf(1,"%5d",ack(i,j)) end for puts(1,"\n") end for printf(1,"ack(4,1) %5d\n",ack(4,1))-- printf(1,"ack(4,2) %5d\n",ack(4,2)) -- power function overflow if getc(0) then end ifend procedure

This is a naive implementation that does not use any optimization. Find the explanation at [[1]]. Computing the Ackermann function for (4,1) is possible, but takes quite a while because the stack grows very fast to large dimensions.

Building an example table (takes a while to compute, though, especially for the last three numbers; also it fails with the last line in Powershell v1 since the maximum recursion depth is only 100 there):

The recursion with ackermann can become very deep indeed. In this way it is still calculable without needing a very big stack. And because memoization is used, you circumvent a stack overflow without a (real) cost.

This program assumes the variables N and M are the arguments of the function, and that the list L1 is empty. It stores the result in the system variable ANS. (Program names can be no longer than 8 characters, so I had to truncate the function's name.)