Ackermann Function

Here is a solution using classical TeX tools (without expl3).

\def\afterfi#1#2\fi{\fi#1}
\def\Ac#1#2{\ifnum#1=0 \afterfi{\the\numexpr#2+1\relax}%
            \else \afterfi{\ifnum#2=0 \afterfi{\Aeval{#1-1}{1}}%
                           \else \afterfi{\Aeval{#1-1}{\Aeval{#1}{#2-1}}}\fi}\fi}
\def\Aeval#1#2{\expanded{\noexpand\Ac{\the\numexpr#1}{\the\numexpr#2}}}
\def\A(#1,#2){$A(#1,#2)=\Ac{#1}{#2}$\par}

\A(0,0)
\A(1,0)
\A(2,0)
\A(0,1)
\A(0,2)
\A(1,1)
\A(2,2)
\A(2,3)
\A(3,3)
\A(3,4)

\bye

The \afterfi macro is used in order to spare TeX stack.


Here is a \romannumeral-expansion-based solution using the bigintcalc-package.

Be aware: The Ackermann-function being defined recursively implies nesting calls to \romannumeral which takes its toll on the semantic nest.

The solutions of egreg, wipet and Marcel Krüger don't have this problem.

\documentclass{article}
\usepackage{amsmath}
\usepackage{bigintcalc}

\newcommand\UDfirstoftwo[2]{#1}%
\newcommand\UDsecondoftwo[2]{#2}%
\newcommand\UDPassFirstToSecond[2]{#2{#1}}%
\csname @ifdefinable\endcsname\UDstopromannumeral{\chardef\UDstopromannumeral=`\^^00}%

% \Ackermann{m}{n}

\newcommand\Ackermann{%
  \romannumeral\Ackermannloop
}%

\newcommand\Ackermannloop[2]{%
  \ifnum\bigintcalcCmp{#1}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
  {\expandafter\expandafter\expandafter\UDstopromannumeral\bigintcalcInc{#2}}{%
    \ifnum\bigintcalcCmp{#2}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
    {%
       \expandafter\expandafter\expandafter\Ackermannloop\expandafter\expandafter\expandafter{\bigintcalcDec{#1}}{1}%
    }%
    {%
       \expandafter\UDPassFirstToSecond\expandafter{%
         \romannumeral
         \expandafter\expandafter\expandafter\UDPassFirstToSecond
         \expandafter\expandafter\expandafter{\bigintcalcDec{#2}}{\Ackermannloop{#1}}}{%
         \expandafter\expandafter\expandafter\Ackermannloop\expandafter\expandafter\expandafter{\bigintcalcDec{#1}}%
      }%
    }%
  }%
}%

\begin{document}

$\text{Ackermann}(0, 0)=\Ackermann{0}{0}$

$\text{Ackermann}(1, 0)=\Ackermann{1}{0}$

$\text{Ackermann}(2, 0)=\Ackermann{2}{0}$

$\text{Ackermann}(0, 1)=\Ackermann{0}{1}$

$\text{Ackermann}(0, 2)=\Ackermann{0}{2}$

$\text{Ackermann}(1, 1)=\Ackermann{1}{1}$

$\text{Ackermann}(2, 2)=\Ackermann{2}{2}$

$\text{Ackermann}(2, 3)=\Ackermann{2}{3}$

$\text{Ackermann}(3, 3)=\Ackermann{3}{3}$

$\text{Ackermann}(3, 4)=\Ackermann{3}{4}$

% \Ackermann{4}{2}
% I suppose the above yields something like:
% ! TeX capacity exceeded, sorry [input stack size=5000].

\end{document}

enter image description here


Of course this needs a LuaTeX answer. I optimized some of the easy cases, but it is based on 64bit signed integers, so it fails whenever any value gets bigger than 2^63-1=9223372036854775807. It does check for this though:

\documentclass{article}
\directlua{
  local maxint = math.maxinteger
  local almostmaxint = math.maxinteger
  local almosthalfmaxinteger = maxint/2-2
  local function A(m, n)
    if m == 0 then
      if n==maxint then
        error[[Overflow]]
      end
      return n+1 end
    if n == 0 then return A(m-1, 1) end
    if m == 1 then
      if n==almostmaxint or n ==maxint then
        error[[Overflow]]
      end
      return n+2
    end % Optimize simple case
    if m == 2 then
      if n > almosthalfmaxinteger then
        error[[Overflow]]
      end
      return 2*n+3
    end % Optimize simple case
    return A(m-1, A(m, n-1))
  end
  ackermann = A
}
\NewExpandableDocumentCommand\ackermann{mm}{\directlua{tex.write(ackermann(token.scan_int(), token.scan_int()))} \numexpr#1\relax \numexpr#2\relax}

\begin{document}

$A(0,0)=\ackermann{0}{0}$

$A(1,0)=\ackermann{1}{0}$

$A(2,0)=\ackermann{2}{0}$

$A(0,1)=\ackermann{0}{1}$

$A(0,2)=\ackermann{0}{2}$

$A(1,1)=\ackermann{1}{1}$

$A(2,2)=\ackermann{2}{2}$

$A(2,3)=\ackermann{2}{3}$

$A(3,3)=\ackermann{3}{3}$

$A(3,7)=\ackermann{3}{7}$

$A(3,8)=\ackermann{3}{8}$

$A(3,9)=\ackermann{3}{9}$

$A(3,20)=\ackermann{3}{20}$

$A(3,40)=\ackermann{3}{40}$

$A(4,0)=\ackermann{4}{0}$

$A(4,1)=\ackermann{4}{1}$

\end{document}

enter image description here