LaTeX 中的简单递归

LaTeX 中的简单递归

我正在尝试进入 LaTeX 递归并创建了一个命令\tower[2][3][4][2]返回电力塔,,2^{3^{4^2}}任意数量的参数。我的尝试:

\documentclass{beamer}
\usepackage{xparse}

\NewDocumentCommand\tower{o}{%
  \IfValueT{#1}{\towerstep{#1}}}
\NewDocumentCommand\towerstep{m}{%
   #1^\tower}

\begin{document}
    \begin{frame}
        \tower[2][3][4][2]
    \end{frame}
\end{document}

这会产生很多错误,但会给出正确的输出。错误来自不在数学模式下的表达式(添加$使情况变得更糟)以及缺少括号。我认为这与命令展开的顺序有关。我该如何修复代码?

答案1

本着持续编程精神的解决方案:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand \towerAux { m o }
  {
    \IfValueTF { #2 }
      { \towerAux {{#1}{#2}} }
      { \__tower:nn {#1} { } }
  }

\cs_set:Npn \__tower:nn #1 #2 
  {
    \tl_if_empty:nTF { #1 }
      { #2 }
      { \__tower_i:nnn #1 { #2 } }
  }

\cs_set:Npn \__tower_i:nnn #1 #2 #3 { \__tower:nn { #1 } { #2 ^ { #3 } } }

\NewDocumentCommand \tower { } { \towerAux { } }
\ExplSyntaxOff

\begin{document}
$\tower[5][3][4][2]$
\end{document}

使用该程序,$\tower[5][3][4][2]$将依次替换以下指令:

$\tower[5][3][4][2]$

$\towerAux{}[5][3][4][2]$

$\towerAux{{}{5}}[3][4][2]$

$\towerAux{{{}{5}}{3}}[4][2]$

$\towerAux{{{{}{5}}{3}}{4}}[2]$

$\towerAux{{{{{}{5}}{3}}{4}}{2}}$

如你所见,\towerAux是递归的。

现在,所有参数(如果我可以这么说)都已构造成一种列表,最后一个参数是第一个可访问的。现在,您可以像在递归编程中一样,在一种辅助参数(末尾)中构造所需的结果。命令\__tower:nn\__tower_i:nnn是相互递归的。

$\__tower:nn{{{{{}{5}}{3}}{4}}{2}}{}$

$\__tower_i:nnn{{{{}{5}}{3}}{4}}{2}{}$

$\__tower:nn{{{{}{5}}{3}}{4}}{2^{}}$

$\__tower_i:nnn{{{}{5}}{3}}{4}{2^{}}$

$\__tower:nn{{{}{5}}{3}}{4^{2^{}}}$

$\__tower_i:nnn{{}{5}}{3}{4^{2^{}}}$

$\__tower:nn{{}{5}}{3^{4^{2^{}}}}$

$\__tower_i:nnn{}{5}{3^{4^{2^{}}}}$

$\__tower_i:nnn{}{5^{3^{4^{2^{}}}}}$

$5^{3^{4^{2^{}}}}$

答案2

\documentclass[border=15pt]{standalone}
\makeatletter
\def\tower{\@ifnextchar[{\def\endtower{}\towerstep}{}}%
\def\towerstep[#1]{#1%
  \@ifnextchar[{\edef\endtower{\endtower\egroup}^\bgroup\towerstep}{\endtower}}
\makeatother
\begin{document}
        $\tower[2][3][4][2]$ 
        $\tower[2][3][4]$ 
        $\tower[2][3]$ 
        $\tower[2]$ 
        $\tower$ 

\end{document}

在此处输入图片描述

答案3

我建立了两个标记列表,第一个包含

{1^{2^{3^{4^{5^{6^{7

另一个包含

}}}}}}}

实际上,括号存储为\c_group_begin_token\c_group_end_token,因此标记列表是平衡的。

如果[有,则采取进一步措施。最后,交付两个列表。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\tower}{}
 {
  \tl_clear:N \l__perner_tower_left_tl
  \tl_clear:N \l__perner_tower_right_tl
  \perner_tower_build:n { }
 }

\tl_new:N \l__perner_tower_left_tl
\tl_new:N \l__perner_tower_right_tl

\cs_new_protected:Nn \perner_tower_build:n
 {
  \peek_charcode:NTF [
   {% there is a [
    \__perner_tower_add:nw { #1 }
   }
   {% no [, end
    \__perner_tower_end:
   }
 }
    
\cs_new_protected:Npn \__perner_tower_add:nw #1 [#2]
 {
  \tl_put_right:Nn \l__perner_tower_left_tl { #1 \c_group_begin_token #2 }
  \tl_put_right:Nn \l__perner_tower_right_tl { \c_group_end_token }
  \perner_tower_build:n { \c_math_superscript_token }
 }

\cs_new_protected:Npn \__perner_tower_end:
 {
  \tl_use:N \l__perner_tower_left_tl
  \tl_use:N \l__perner_tower_right_tl
 }
\ExplSyntaxOff

\begin{document}

$\tower[1][2][3][4][5][6][7]$

\end{document}

使用不同的语法,更简短。参数以逗号分隔;然后我们输出任意两个项^{(再次作为隐式标记),最后}输出正确数量的。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\tower}{m}
 {
  \perner_tower_build:n { #1 }
 }

\seq_new:N \l__perner_tower_seq

\cs_new_protected:Nn \perner_tower_build:n
 {
  \seq_set_split:Nnn \l__perner_tower_seq { , } { #1 }
  \seq_use:Nn \l__perner_tower_seq { \c_math_superscript_token \c_group_begin_token }
  \prg_replicate:nn { \seq_count:N \l__perner_tower_seq - 1 } { \c_group_end_token }
 }
\ExplSyntaxOff

\begin{document}

$\tower{1,2,3,4,5,6,7}$

\end{document}

在此处输入图片描述

答案4

也许是这样的:

\documentclass{beamer}
\usepackage{xparse}
%-----------------------------------------------------------------------------
% In case there is an optional argument \tower calls \towerreverseloop:
%-----------------------------------------------------------------------------
\NewDocumentCommand\tower{o}{%
  \IfValueT{#1}{\towerreverseloop{[{#1}]}}%
}%
%-----------------------------------------------------------------------------
% \towerreverseloop reverses the order of the list of optional arguments.
% #1 holds the reversed list of optional arguments gathered so far.
% #2 is the next optional argument.
% If there are no more optional arguments to put into reversed order, 
% then \towerinitializeconstructexpressionloop is applied to the reversed
% list of optional arguments gathered so far.
%-----------------------------------------------------------------------------
\NewDocumentCommand\towerreverseloop{mo}{%
  \IfValueTF{#2}{%
    \towerreverseloop{[{#2}]#1}%
  }{%
    \towerinitializeconstructexpressionloop#1%
  }%
}%
%-----------------------------------------------------------------------------
% \towerinitializeconstructexpressionloop calls \towerconstructexpressionloop,
% hereby initializing \towerconstructexpressionloop's "expression constructed
% so far"-argument with the first element of the reversed list of optional
% arguments.
%-----------------------------------------------------------------------------
\NewDocumentCommand\towerinitializeconstructexpressionloop{o}{%
  \towerconstructexpressionloop{#1}%
}%
%-----------------------------------------------------------------------------
% \towerconstructexpressionloop constructs the desired expression from the
% elements of the reversed list of optional arguments.
% #1 holds the expression constructed so far.
% #2 next optional argument/next element of the reversed list of
%    optional arguments.
%-----------------------------------------------------------------------------
\NewDocumentCommand\towerconstructexpressionloop{mo}{%
  \IfValueTF{#2}%
            {\towerconstructexpressionloop{#2^{#1}}}%
            {#1%
             %\def\result{#1}\show\result
            }%
}%
\begin{document}
    \begin{frame}[fragile]
        \verb|$\tower[2][3][4][2]$|: $\tower[2][3][4][2]$\\
        \verb|$\tower[2][3][4]$|: $\tower[2][3][4]$\\
        \verb|$\tower[2][3]$|: $\tower[2][3]$\\
        \verb|$\tower[2]$|: $\tower[2]$\\
        \verb|$\tower$|: $\tower$
    \end{frame}
\end{document}

在此处输入图片描述

相关内容