Simple recursion in LaTeX
\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}
A solution in the spirit of the programmation by continuation:
\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}
With this programmation, $\tower[5][3][4][2]$
is replaced successively by the following instructions:
$\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}}$
As you see, \towerAux
is recursive.
Now, all the arguments (if I can say) have been structured in a kind of list and the last one is the first accessible. You can now construct the required result in a kind of auxiliary argument (at the end) as usual in recursive programmation. The commands \__tower:nn
and \__tower_i:nnn
are mutually recursive.
$\__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^{}}}}$
I build two token lists, the first containing
{1^{2^{3^{4^{5^{6^{7
and the other containing
}}}}}}}
Actually, the braces are stored as \c_group_begin_token
and \c_group_end_token
, so the token lists are balanced.
If [
follows, a further step is taken. At the end, the two lists are delivered.
\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}
Much shorter with a different syntax. The argument is split at commas; then between any two items we output ^{
(again as implicit tokens) and at the end the right number of }
is output.
\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}