如何在 (La)TeX 中创建递归宏?

如何在 (La)TeX 中创建递归宏?

以下 MWE 是我尝试翻译的代码我在 C# 中的工作算法到 (La)TeX。我不明白为什么它不起作用。你能探究问题的根源吗?

评论:

  1. #1是一个二进制元素列表。字符1(向上移动)或0(向右移动)将递归地附加到此列表中。一开始它是一个空列表。
  2. #2表示剩余向右移动的次数。
  3. #3表示剩余的向上移动次数。
\documentclass{article}
\usepackage{ifthen,pgf}

\parindent=0pt

\newcommand{\Populate}[3]%
{%
        \ifthenelse{#2=0}% on the most left border?
        {% 
                \ifthenelse{#3=0}% on the most top border?
                {% 
                        #1\endgraf% I need to trim the most left comma later!
                }%
                {% 
                        % move upward
                        \pgfmathtruncatemacro{\ups}{#3-1}%
                        \Populate{#1,1}{#2}{\ups}%
                }%  
        }%      
        {% 
                \ifthenelse{#2=#3}% on the diagonal border?
                {%
                        % move to the right
                        \pgfmathtruncatemacro{\rights}{#2-1}%
                        \Populate{#1,0}{\rights}{#3}%
                }%
                {%
                        % move to the right
                        \pgfmathtruncatemacro{\rights}{#2-1}%
                        \Populate{#1,0}{\rights}{#3}%
                        % move upward
                        \pgfmathtruncatemacro{\ups}{#3-1}%
                        \Populate{#1,1}{#2}{\ups}%
                }%
        }%      
}


\begin{document}
\Populate{}{4}{4}
\end{document}

它产生了如下错误输出:

,0,0,0,0,1,1,1,1
,0,0,0,1,1,1,1
,0,0,1,1,1,1
,0,1,1,1,1

预期输出必须如下所示:(前面的逗号稍后将被删除)

,0,0,0,0,1,1,1,1
,0,0,0,1,0,1,1,1
,0,0,0,1,1,0,1,1
,0,0,0,1,1,1,0,1
,0,0,1,0,0,1,1,1
,0,0,1,0,1,0,1,1
,0,0,1,0,1,1,0,1
,0,0,1,1,0,0,1,1
,0,0,1,1,0,1,0,1
,0,1,0,0,0,1,1,1
,0,1,0,0,1,0,1,1
,0,1,0,0,1,1,0,1
,0,1,0,1,0,0,1,1
,0,1,0,1,0,1,0,1

最后编辑:

例如N x N,使用它\Populate{0}{N-1}{N}可以避免额外的工作来删除上面的前导逗号。(我刚刚得到了这个启示)

答案1

您必须使用更多组({...})来本地化(重新)定义您的宏\upsrights

\documentclass{article}
\usepackage{ifthen,pgf}

\parindent=0pt

\newcommand{\Populate}[3]%
{%
  \ifthenelse{#2=0}% on the most left border?
  {% 
    \ifthenelse{#3=0}% on the most top border?
    {% 
      #1\endgraf% I need to trim the most left comma later!
    }%
    {%
        % move upward
        \pgfmathtruncatemacro{\ups}{#3-1}%
        \Populate{#1,1}{#2}{\ups}%
    }%  
  }%      
  {% 
    \ifthenelse{#2=#3}% on the diagonal border?
    {%
        % move to the right
        \pgfmathtruncatemacro{\rights}{#2-1}%
        \Populate{#1,0}{\rights}{#3}%
    }%
    {%
      {% GROUP
        % move to the right
        \pgfmathtruncatemacro{\rights}{#2-1}%
        \Populate{#1,0}{\rights}{#3}%
      }%
        % move upward
        \pgfmathtruncatemacro{\ups}{#3-1}%
        \Populate{#1,1}{#2}{\ups}%
    }%
  }%      
}


\begin{document}
\Populate{}{4}{4}
\end{document}

评论: A不是一个功能。您的问题应该是“如何在 (La)TeX 中创建递归宏?”。

答案2

这是我做的最简单的版本。如果你有更简单的版本,请编辑此答案。

\documentclass{minimal}

\newcount\u
\newcount\r

\def\d#1{\advance#1-1\relax}

\newcommand{\Populate}[3]{%
        \r#2\u#3%
        \ifnum\r=0
                \ifnum\u=0\relax
                        #1\endgraf
                \else
                        \d\u\Populate{#1,1}{#2}{\the\u}%
                \fi
        \else
                \ifnum\r=\u
                        \d\r\Populate{#1,0}{\the\r}{#3}%
                \else                       
                        {\d\r\Populate{#1,0}{\the\r}{#3}}% must be grouped!
                        \d\u\Populate{#1,1}{#2}{\the\u}%
                \fi
        \fi}


\begin{document}
\Populate{0}{3}{4}
\end{document}

相关内容