阿克曼宏

阿克曼宏

我是这个网站的新手,还在学习 LaTeX/TeX 的阶段。最近我偶然发现了阿克曼函数练习,但我仍然不知道如何正确完成它。那时我开始在网上查找是否已经有解决方案,但我什么也找不到,除了这个问题

我的问题是我不知道如何使用expl3,因为我们还没有学过它,所以我们被告知只需创建一个“基本”解决方案,就可以计算出阿克曼函数的下项。

回顾一下,阿克曼函数定义如下

在此处输入图片描述

它看起来像一个非常无害的递归函数,但是速度非常快,由于数字太大会导致超时。

这让我回想起计算阿克曼函数。给出了许多解决方案来计算解决方案,但我想知道是否有可能“更新”宏,以便它显示到不同的阶段。例如,调用\Ackermann{2}{0}将产生在此处输入图片描述

或者调用 `\Ackermann{2}{2} 将得到在此处输入图片描述

再次,我重复一遍,我们被告知要创建一个“基本”宏,因此无需担心计算\A{10}{49}

我希望你理解得很清楚,提前谢谢你。Lea

编辑:我试图通过分析解决方案来取得一点进展这个问题,我设法理解了(或者说我认为如此)其中一个解决方案。我能够复制 @wipet 的解决方案,但没有使用,\afterfi因为我不太理解它。以下是代码

\begin{document}

\makeatletter
\def\A#1#2{%
    \ifnum#1=\z@
        \number\numexpr#2+1\relax%
    \else 
        \ifnum#2=\z@
            \A@i{\numexpr#1-1\relax}{1}%
    \else
        \A@i{\numexpr#1-1\relax}{\expanded{\A@i{#1}{\numexpr#2-1\relax}}}%
    \fi\fi%
}
\def\A@i#1#2{\expanded{\noexpand\A{#1}{#2}}}

\def\acker@values{}
\def\update@values#1{%
    \edef\acker@values{\acker@values #1}
}
\makeatother

\end{document}

我想使用\acker@values\update@values存储不同的步骤,但我搞不懂。我现在的问题是无法显示步骤。

答案1

这是另一次尝试——这次没有使用\romannumeral-expansion。
相反,该例程\Ackermann使用了\expanded

它比\romannumeral我的其他答案中的 -attempt 更快。

尽管如此,仍需注意:

\Ackermannsteps{3}{3}
\Ackermannsteps{3}{4}打印53 张 A4 纸,其中许多行超出了 A4 纸的宽度。! TeX capacity exceeded, sorry [main memory size=5000000].

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

\newcommand\UDfirstoftwo[2]{#1}%
\newcommand\UDsecondoftwo[2]{#2}%
\newcommand\UDPassFirstToSecond[2]{#2{#1}}%

\DeclareMathOperator{\AckermannFunction}{A}

% -------------------------------------------------------------------------------
% Ackermann-function:
%
% A(m,n) :=  if m = 0 : n+1
%            if m > 0 and n = 0: A(m-1, 1)
%            if m > 0 and n > 0: A(m-1, A(m, n-1))
% m non-negative integer 
% n non-negative integer
%--------------------------------------------------------------------------------
%%
%================================================================================
%
% \Ackermann{m}{n}
%
% Delivers the solution after two "hits" by \expandafter
%
%--------------------------------------------------------------------------------
\newcommand\Ackermann[2]{%
  \expanded{\Ackermannloop{#1}{#2}}%
}%
\newcommand\Ackermannloop[2]{%
  \ifnum\bigintcalcCmp{#1}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
  {\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{%
        \expanded{%
          \expandafter\expandafter\expandafter\UDPassFirstToSecond
          \expandafter\expandafter\expandafter{\bigintcalcDec{#2}}{\Ackermannloop{#1}}%
        }%
      }{%
        \expandafter\expandafter\expandafter\Ackermannloop
        \expandafter\expandafter\expandafter{\bigintcalcDec{#1}}%
      }%
    }%
  }%
}%
%================================================================================
%
% \Ackermannsteps{<m>}{<n>}
%
% Prints the single steps of computing the Ackermann-function.
% Delivers all steps after two "hits" by \expandafter
%
%--------------------------------------------------------------------------------
\newcommand\Ackermannsteps[2]{%
  \noindent\rlap{$\AckermannFunction(#1, #2)$}\Ackermannstepsloop{#1}{#2}{$\phantom{\AckermannFunction(#1, #2){}}=}{$\\}%
}%
\newcommand\Ackermannstepsloop[4]{%
  % #1 = m
  % #2 = n
  % #3 = tokens to prepend to the term developped
  % #3 = tokens to append to the term developped
  \ifnum\bigintcalcCmp{#1}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
  {#3\bigintcalcInc{#2}#4}{%
    \ifnum\bigintcalcCmp{#2}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
    {%
       #3\AckermannFunction(\bigintcalcDec{#1}, 1)#4%
       \expandafter\expandafter\expandafter\Ackermannstepsloop
       \expandafter\expandafter\expandafter{\bigintcalcDec{#1}}{1}%
    }%
    {%
      #3\AckermannFunction(\bigintcalcDec{#1}, \AckermannFunction(#1, \bigintcalcDec{#2}))#4%
      \expandafter\expandafter\expandafter\UDPassFirstToSecond
      \expandafter\expandafter\expandafter{\bigintcalcDec{#2}}{\Ackermannstepsloop{#1}}%
      {#3\AckermannFunction(\bigintcalcDec{#1}, }{)#4}%
      \expandafter\UDPassFirstToSecond\expandafter{%
        \expanded{%
          \expandafter\expandafter\expandafter\UDPassFirstToSecond
          \expandafter\expandafter\expandafter{\bigintcalcDec{#2}}{\Ackermannloop{#1}}%
        }%
      }{%
        \expandafter\expandafter\expandafter\Ackermannstepsloop
        \expandafter\expandafter\expandafter{\bigintcalcDec{#1}}%
      }%
    }%
    {#3}{#4}%
  }%
}%


\begin{document}

\noindent Testing \verb|\Ackermannsteps|: \bigskip

%\Ackermannsteps{0}{0} \bigskip

\Ackermannsteps{2}{0} \bigskip

%\Ackermannsteps{2}{1} \bigskip

\Ackermannsteps{2}{2} \bigskip

%\Ackermannsteps{2}{3} \bigskip

%\Ackermannsteps{2}{4} \bigskip

%\Ackermannsteps{3}{2} \bigskip

%\Ackermannsteps{3}{1} \bigskip

%\Ackermannsteps{3}{2} \bigskip

%\Ackermannsteps{3}{3} \bigskip

% \Ackermannsteps{3}{4}
% I suppose the above yields something like:
% ! TeX capacity exceeded, sorry [main memory size=5000000].


\newpage

\noindent Testing \verb|\Ackermann|: \bigskip

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

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

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

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

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

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

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

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

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

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

$\AckermannFunction(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}

在此处输入图片描述

在此处输入图片描述



稍加修改即可:

如果您愿意,您可以记录已经计算出阿克曼函数值的参数对。如果已经记录了参数对,则可以采用捷径,只需提供结果,而不是提供所有步骤。

例如,可以通过定义名称为模式的宏来完成录制。然后可以通过调用这些宏(如果已定义)来实现快捷方式。Ack(⟨m⟩)(⟨n⟩)

这依赖于

  • 整数参数\globaldefs不具有正值。
  • 命令命名空间是可以自由使用的。\Ack(⟨non-negative integer 1⟩)(⟨non-negative integer 2⟩)

由于已经计算的阿克曼函数值的记录是通过本地定义宏来保存的,因此\Ackermannsteps不可扩展,需要更多内存。更容易发生 TeX 容量超出错误。与其存储已经计算的阿克曼函数值(这些值可能非常大,因此可能需要大量标记,存储可能会消耗大量内存),不如维护一个参数值对列表,如果传递给的参数\Ackermannstepsloop已经在列表中,则只需调用\Ackermannloop获取数字,而不是执行整个递归步骤打印例程。这样,就不会存储每个已经计算的阿克曼函数值。因此这可能需要更少的内存。但相同的阿克曼函数值将被重复计算。因此这会更耗时。

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

\newcommand\UDfirstoftwo[2]{#1}%
\newcommand\UDsecondoftwo[2]{#2}%
\newcommand\UDPassFirstToSecond[2]{#2{#1}}%
\newcommand\UDexchange[2]{#2#1}%
\makeatletter
\@ifdefinable\Stopromannumeral{\chardef\Stopromannumeral=`\^^00}%
\@ifdefinable\CsNameToCsToken{%
  \long\def\CsNameToCsToken#1#{\romannumeral\InnerCsNameToCsToken{#1}}%
}%
\newcommand\InnerCsNameToCsToken[2]{%
  \expandafter\UDexchange\expandafter{\csname#2\endcsname}{\Stopromannumeral#1}%
}%
\makeatother


% -------------------------------------------------------------------------------
% Ackermann-function:
%
% A(m,n) :=  if m = 0 : n+1
%            if m > 0 and n = 0: A(m-1, 1)
%            if m > 0 and n > 0: A(m-1, A(m, n-1))
% m non-negative integer 
% n non-negative integer
%--------------------------------------------------------------------------------
%%
%================================================================================
%
% \Ackermann{m}{n}
%
% Delivers the solution after two "hits" by \expandafter
%
%--------------------------------------------------------------------------------
\newcommand\Ackermann[2]{%
  \expanded{\Ackermannloop{#1}{#2}}%
}%
\newcommand\Ackermannloop[2]{%
  \ifnum\bigintcalcCmp{#1}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
  {\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{%
        \expanded{%
          \expandafter\expandafter\expandafter\UDPassFirstToSecond
          \expandafter\expandafter\expandafter{\bigintcalcDec{#2}}{\Ackermannloop{#1}}%
        }%
      }{%
        \expandafter\expandafter\expandafter\Ackermannloop
        \expandafter\expandafter\expandafter{\bigintcalcDec{#1}}%
      }%
    }%
  }%
}%
%================================================================================
%
% \Ackermannsteps{<m>}{<n>}
%
% Prints the single steps of computing the Ackermann-function.
% Delivers all steps after two "hits" by \expandafter
%
%--------------------------------------------------------------------------------
\DeclareMathOperator{\AckermannFunction}{A}%
\newcommand\Ackermannsteps[2]{%
  \begingroup
  \noindent\rlap{$\AckermannFunction(#1, #2)$}\Ackermannstepsloop{#1}{#2}{$\phantom{\AckermannFunction(#1, #2){}}=}{$\\}%
  \endgroup
}%
\newcommand\Ackermannstepsloop[4]{%
  % #1 = m
  % #2 = n
  % #3 = tokens to prepend to the term developped
  % #3 = tokens to append to the term developped
  \CsNameToCsToken{@ifundefined}{Ack(#1)(#2)}{%
    \CsNameToCsToken\edef{Ack(#1)(#2)}{\Ackermannloop{#1}{#2}}%
    \ifnum\bigintcalcCmp{#1}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
    {#3\bigintcalcInc{#2}#4}{%
      \ifnum\bigintcalcCmp{#2}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
      {%
         #3\AckermannFunction(\bigintcalcDec{#1}, 1)#4%
         \expandafter\expandafter\expandafter\Ackermannstepsloop
         \expandafter\expandafter\expandafter{\bigintcalcDec{#1}}{1}%
      }%
      {%
        #3\AckermannFunction(\bigintcalcDec{#1}, \AckermannFunction(#1, \bigintcalcDec{#2}))#4%
        \expandafter\expandafter\expandafter\UDPassFirstToSecond
        \expandafter\expandafter\expandafter{\bigintcalcDec{#2}}{\Ackermannstepsloop{#1}}%
        {#3\AckermannFunction(\bigintcalcDec{#1}, }{)#4}%
        \expandafter\UDPassFirstToSecond\expandafter{%
          \expanded{%
            \CsNameToCsToken{@ifundefined}{Ack(#1)(\bigintcalcDec{#2})}{%
              \expandafter\expandafter\expandafter\UDPassFirstToSecond
              \expandafter\expandafter\expandafter{\bigintcalcDec{#2}}{\Ackermannloop{#1}}%
            }{%
              \CsNameToCsToken{Ack(#1)(\bigintcalcDec{#2})}%
            }%
          }%
        }{%
          \expandafter\expandafter\expandafter\Ackermannstepsloop
          \expandafter\expandafter\expandafter{\bigintcalcDec{#1}}%
        }%
      }%
      {#3}{#4}%
    }%
  }{%
    #3\CsNameToCsToken{Ack(#1)(#2)}#4%
  }%
}%




\begin{document}

\noindent Testing \verb|\Ackermannsteps|: \bigskip

%\Ackermannsteps{0}{0} \bigskip

\Ackermannsteps{2}{0} \bigskip

%\Ackermannsteps{2}{1} \bigskip

\Ackermannsteps{2}{2} \bigskip

%\Ackermannsteps{2}{3} \bigskip

%\Ackermannsteps{2}{4} \bigskip

%\Ackermannsteps{3}{2} \bigskip

%\Ackermannsteps{3}{1} \bigskip

%\Ackermannsteps{3}{2} \bigskip

%\Ackermannsteps{3}{3} \bigskip

% \Ackermannsteps{3}{4}
% I suppose the above yields something like:
% ! TeX capacity exceeded, sorry [main memory size=5000000].

\end{document}

在此处输入图片描述

答案2

我建议使用\romannumeral扩展驱动的尾递归宏,它维护迄今为止计算的术语列表,您可以在其中指定参数,这些参数表示在迭代完成时迄今为止计算的术语列表的每个项目应嵌套在标记之间。

\romannumeral-扩展,以便您准确地知道获取结果的数量\expandafter,这对于获得嵌套调用的结果非常重要。

请注意:这非常慢并且\Ackermannsteps{3}{3}会导致出现! TeX capacity exceeded, sorry [main memory size=5000000]-error或类似错误。

并且这不会通过重新使用已经计算出的阿克曼函数值来走捷径。

如果您想要这个,请查看我的其他答案。

您也可以扩展地执行此操作,但这意味着需要进行大量的列表累积和迭代来检测某个值是否已经计算出来。由于使用 Ackermann 时无论如何都会受到内存溢出的威胁,因此无需通过编造宏参数来增加风险,这些宏参数应该包含在某些情况下表示非常大数字的长标记列表。

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

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


% -------------------------------------------------------------------------------
% Ackermann-function:
%
% A(m,n) :=  if m = 0 : n+1
%            if m > 0 and n = 0: A(m-1, 1)
%            if m > 0 and n > 0: A(m-1, A(m, n-1))
% m non-negative integer 
% n non-negative integer
%--------------------------------------------------------------------------------
%%
%================================================================================
%
% \Ackermann{m}{n}
%
% Delivers the solution after two "hits" by \expandafter
%
%--------------------------------------------------------------------------------
\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}}%
      }%
    }%
  }%
}%
%================================================================================
%
% \Ackermannsteps{<m>}{<n>}
%
% Prints the single steps of computing the Ackermann-function.
% Delivers all steps after two "hits" by \expandafter
%
%--------------------------------------------------------------------------------
%
% \Ackermannsteps does: \romannumeral\Ackermannstepsloop{<m>}{<n>}{}{\\&=}{}{tablehead}{tablefoot}{\UDfirstoftwo}
%
% Syntax of \Ackermannstepsloop:
%
% \romannumeral
% \Ackermannstepsloop{<m>}%
%                    {<n>}%
%                    {<list of terms developed so far>}%
%                    {Outermost instance: <tokens to put between list items> 
%                     Nested instances: <tokens to prepend to each list item>}%
%                    {Outermost instance: <more tokens to put between list items>
%                     Nested instances: <tokens to append to each list item>}%
%                    {<tokens to prepend to entire list>}%
%                    {<tokens to append to entire list>}%
%                    {<marker for outermost loop/nested loop: \UDfirstoftwo/UDsecondoftwo>}%
%
% Pseudocode of \Ackermannstepsloop:
%
% If <m> = 0:           ( This case is done by the macro \AckermannstepsCaseA )
%                       Iterate on <list of terms developed so far>{<n>+1}, putting things between
%                       the list items. Deliver the result thereof, wrapped between 
%                       <tokens to prepend to entire list> and 
%                       <tokens to append to entire list>.
%              
% If m > 0 and  n = 0:  ( This is done by the macro \AckermannstepsCaseB )
%                       Call \Ackermannstepsloop with arguments changed as follows:
%                         - <list of terms developed so far> := <list of terms developed so far> + {A(<m>-1, 1)} 
%                         - n := 1
%                         - <m> := <m>-1
%                         The other arguments remain unchanged.
%
% If m > 0 and n > 0:   ( This is done by the macro \AckermannstepsCaseC )
%                       Call \Ackermannstepsloop with arguments changed as follows:
%                         - <list of terms developed so far> :=
%                               <list of terms developed so far> + {A(<m-1>, A(<m>, <n-1>))} +
%                               \romannumeral\Ackermannstepsloop{<m>}{<n-1>}{}{A(<m-1>,}{)}{}{}{\UDsecondoftwo}
%                         - <n> := Ackermann(<m>, <n>-1)
%                         - <m> := <m>-1
%                         The other arguments remain unchanged.
%
\DeclareMathOperator{\AckermannFunction}{A}
\newcommand\Ackermannsteps[2]{%
  \romannumeral\Ackermannstepsloop{#1}{#2}{}{$\\$\phantom{\AckermannFunction(#1, #2){}}=}{}{\noindent$\AckermannFunction(#1, #2)=}{$}{\UDfirstoftwo}%
}%
\newcommand\Ackermannstepsloop[8]{%
  % #1 = <m>
  % #2 = <n>
  % #3 = <list of terms developed so far>
  % #4 = Outermost instance: <tokens to put between list items> Nested instances: <tokens to prepend to each list item>
  % #5 = Outermost instance: <more tokens to put between list items> Nested instances: <tokens to append to each list item>
  % #6 = <tokens to prepend to entire list>
  % #7 = <tokens to append to entire list>
  % #8 = <marker for outermost loop/nested loop: \UDfirstoftwo/UDsecondoftwo>
  \ifnum\bigintcalcCmp{#1}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
  {%
    \expandafter\expandafter\expandafter\AckermannstepsCaseA
    \expandafter\expandafter\expandafter{\bigintcalcInc{#2}}{#3}%
  }{%
    \ifnum\bigintcalcCmp{#2}{0}=0 \expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
    {%
      \expandafter\expandafter\expandafter\AckermannstepsCaseB
      \expandafter\expandafter\expandafter{\bigintcalcDec{#1}}{#3}%
    }%
    {%
      \expandafter\expandafter\expandafter\UDPassFirstToSecond
      \expandafter\expandafter\expandafter{\bigintcalcDec{#2}}{%
        \expandafter\expandafter\expandafter\AckermannstepsCaseC
        \expandafter\expandafter\expandafter{\bigintcalcDec{#1}}%
      }{#1}{#3}%
    }%
  }%
  {#4}{#5}{#6}{#7}{#8}%
}%
\newcommand\AckermannstepsCaseA[7]{%
  % #1 = <n>+1
  % #2 = <list of terms developed so far>
  % #3 = Outermost instance: <tokens to put between list items> Nested instances: <tokens to prepend to each list item>
  % #4 = Outermost instance: <more tokens to put between list items> Nested instances: <tokens to append to each list item>
  % #5 = <tokens to prepend to entire list>
  % #6 = <tokens to append to entire list>
  % #7 = <marker for outermost loop/nested loop: \UDfirstoftwo/UDsecondoftwo>
  \expandafter\UDExchange
  \expandafter{%
    \romannumeral#7{\AckermannstepsCaseAOutermostLoop{}{#3#4}}{\AckermannstepsCaseANestedLoop{#3}{#4}}{}#2{#1}\relax
  }{\UDstopromannumeral#5}#6%
}%
\newcommand\AckermannstepsCaseANestedLoop[4]{%
  % #1 = <tokens to prepend to each list item>
  % #2 = <tokens to append to each list item>
  % #3 = <output created so far>
  % #4 = <current item of <list of terms developed so far>> or \relax
  \ifx\relax#4\expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
  {\UDstopromannumeral#3}{%
    \AckermannstepsCaseANestedLoop{#1}{#2}{#3{#2#4#1}}%
  }%
}%
\newcommand\AckermannstepsCaseAOutermostLoop[4]{%
  % #1 = <tokens to prepend in this iteration>
  % #2 = <tokens to prepend in next iteration>
  % #3 = <output created so far>
  % #4 = <current item of <list of terms developed so far>> or \relax
  \ifx\relax#4\expandafter\UDfirstoftwo\else\expandafter\UDsecondoftwo\fi
  {\UDstopromannumeral#3}{%
    \AckermannstepsCaseAOutermostLoop{#2}{#2}{#3#1#4}%
  }%
}%
\newcommand\AckermannstepsCaseB[2]{%
  % #1 = <m>-1
  % #2 = <list of terms developed so far>
  \Ackermannstepsloop{#1}{1}{#2{\AckermannFunction(#1, 1)}}%
}%
\newcommand\AckermannstepsCaseC[4]{%
   % #1 = <m>-1
   % #2 = <n>-1
   % #3 = <m>
   % #4 = <list of terms developed so far>
   \expandafter\UDPassFirstToSecond\expandafter{%
     \romannumeral\expandafter\UDExchange\expandafter{%
       \romannumeral\Ackermannstepsloop{#3}{#2}{}{)}{\AckermannFunction(#1, }{}{}{\UDsecondoftwo}%
     }{\UDstopromannumeral#4{\AckermannFunction(#1, \AckermannFunction(#3, #2))}}%
   }{%
     \expandafter\UDPassFirstToSecond\expandafter{\romannumeral\Ackermannloop{#3}{#2}}{%
        \Ackermannstepsloop{#1}%
     }%
   }%
}%
%================================================================================


\begin{document}

\noindent Testing \verb|\Ackermannsteps|: \bigskip

%\Ackermannsteps{0}{0} \bigskip

\Ackermannsteps{2}{0} \bigskip

%\Ackermannsteps{2}{1} \bigskip

\Ackermannsteps{2}{2} \bigskip

%\Ackermannsteps{2}{3} \bigskip

%\Ackermannsteps{2}{4} \bigskip

%\Ackermannsteps{3}{0} \bigskip

%\Ackermannsteps{3}{1} \bigskip

%\Ackermannsteps{3}{2} \bigskip

% \Ackermannsteps{3}{3}
% I suppose the above yields something like:
% ! TeX capacity exceeded, sorry [main memory size=5000000].


\newpage

\noindent Testing \verb|\Ackermann|: \bigskip

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

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

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

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

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

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

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

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

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

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

$\AckermannFunction(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}

在此处输入图片描述

在此处输入图片描述

相关内容