如何用 LaTeX 打印 {s,u,v,a,t} 的排列?

如何用 LaTeX 打印 {s,u,v,a,t} 的排列?

我想使用 LaTeX 打印集合的排列{s,u,v,a,t}。输出如下所示。

suvat
suvta
suavt
suatv
...

总共有 120 行必须即时生成。

如何用 LaTeX 做到这一点?

梅威瑟:

\documentclass{article}
\begin{document}
.
\end{document}

答案1

这是一个更好的版本,有很多注释!顺便说一句,生成所有排列的方法是基于克努斯洗牌

最新版本的代码避免了嵌套循环,并且分隔符\par偶尔会变成一个标记,以避免构建太大的框(请参阅评论中的讨论)。我用它运行了它abcdefghij并且成功了,尽管生成的文档长达 13746 页。

\documentclass{article}
%\url{http://tex.stackexchange.com/q/112975/86}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\tl_new:N \l__perm_all_tl
\int_new:N \l__perm_int
\int_new:N \l__perm_len_int

% Print the permutations of #2 with prefix #1
\cs_new_nopar:Npn \generate_perms:nn #1#2
{
  % We need to recursively call this function to build up the
  % final list.  This presents us with a dilemma.  Inside the
  % function we need to do some token list manipulations.  These
  % must not propagate upwards to the calling function.  One way
  % to avoid this is to have the function be within a group, but
  % that has two disadvantages: the simplest way leads to a lot of
  % nested groups, and if we want to store the result rather than
  % simply typeset it then the assignments have to be global.
  % So we choose an alternative way which is to ensure that any
  % temporary variables are used as soon as possible after
  % definition and never span a recursive call to the function.
  % This makes the function mildly inefficient in that we can't
  % store and reuse some calculations.
  %
  % How many terms do we need to permute?
  \int_set:Nn \l__perm_len_int {\tl_count:n {#2}}
  \int_compare:nTF {\l__perm_len_int <= 1}
  {
    % Only one, so nothing to do.
    % Add it to the stream with the separator in front.
    \l__perm_sep: #1#2
  }
  {
    % More than one, so need to do the permutations.
    % The method is based on the Knuth shuffle.
    % We need to generate all of the permutations.  We can do this
    % recursively by the following algorithm.  We cyclically permute
    % the token list.  For each cyclic permutation we freeze the first
    % term and then apply the permutation generation function to the
    % rest of the list.
    %
    % Thus if we start with abc we generate the cyclic permutations.
    % These are abc, bca, cab.
    % Then for each of these, we freeze the first term and apply the
    % function to the rest: so with abc we freeze the a and apply the
    % generation function to bc.  This will (by recursion) generate
    % bc and cb, whence appending the a again yields abc and acb.
    %
    % To avoid nesting loops, each iteration creates a token list of
    % what it would do and that list is then inserted into the stream.
    \tl_clear:N \l__perm_all_tl
    \tl_set:Nn \l_tmpb_tl {#2}
    % We "freeze" the first term, adding it to the current prefix.
    \tl_set:Nn \l_tmpa_tl {#1}
    \tl_put_right:Nx \l_tmpa_tl {\tl_head:N \l_tmpb_tl}
    % Now we add the first call to the recursive function to the
    % token list for this iteration.
    % This consists of a call to the function with arguments
    % the new prefix and the new tail.  We pass in the values so
    % that we can now use our temporary variables again with aplomb.
    \tl_put_right:Nn \l__perm_all_tl {\generate_perms:nn}
    \tl_put_right:Nx \l__perm_all_tl {{\exp_not:V \l_tmpa_tl}}
    \tl_put_right:Nx \l__perm_all_tl {{\tl_tail:N \l_tmpb_tl}}
    % Now we repeat the above but applying a cyclic permutation
    % to the main token list first
    \prg_replicate:nn {\l__perm_len_int - 1}
    {
      % This applies a cyclic permutation to the token list.
      \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl {\tl_head:N \l_tmpb_tl}}
      % Then we add the function call to the token list.
      \tl_set:Nn \l_tmpa_tl {#1}
      \tl_put_right:Nx \l_tmpa_tl {\tl_head:N \l_tmpb_tl}
      \tl_put_right:Nn \l__perm_all_tl {\generate_perms:nn}
      \tl_put_right:Nx \l__perm_all_tl {{\exp_not:V \l_tmpa_tl}}
      \tl_put_right:Nx \l__perm_all_tl {{\tl_tail:N \l_tmpb_tl}}
    }
    % The token list now contains all the needed recursive calls
    % which we can now call. 
    \l__perm_all_tl
  }
}

\cs_generate_variant:Nn \generate_perms:nn {VV}

% The optional argument is the separator, the mandatory one is the
% token list to permute.
\DeclareDocumentCommand \permute { O{,~} m }
{
  % Set the separator
  \set_separator:n {#1}
  % Generate the permutation list
  \generate_perms:nn {} {#2}
}

% This sets the separator.  The first separator typesets nothing but
% sets all the subsequent separators.  Normally the separator inserts
% the optional argument from the user but every 120 terms it inserts
% a \par token instead to avoid overload. 
\cs_new_nopar:Npn \set_separator:n #1
{
  \int_zero:N \l__perm_int
  \cs_set:Npn \l__perm_sep:
  {
    \cs_set:Npn \l__perm_sep:
    {
      \int_incr:N \l__perm_int
      \int_compare:nTF {\l__perm_int == 120}
      {
        \par
        \int_zero:N \l__perm_int
      }
      {
        #1
      }
    }
  }
}

\ExplSyntaxOff

\parskip=1em plus 1ex minus .5ex

\begin{document}
\noindent\raggedright\permute{abcdefghi}
\end{document}

abcde 的排列

答案2

使用正确的工具来完成工作:

\documentclass{article}
\usepackage{python}

\begin{document}
\begin{python}
import itertools
for p in itertools.permutations("suvat"): print ''.join(p)
\end{python}
\end{document}

用 运行它pdflatex -shell-escape

答案3

\permute宏是纯 TeX,因此非常便于移植。为什么你不想让它神秘?它神秘地完成了工作!

% New simplified code -- less cryptic than before :-)
\documentclass{article}
\def\recurse#1#2#3#4\endmarker{%
  \dopermute{#1#3}#2#4\endmarker
  \ifx\relax#4\relax\else % add a \par before \else if there are more than 8 items
    \recurse{#1}{#2#3}#4\endmarker
  \fi}
\def\dopermute#1#2#3\endmarker{%
  \ifx\relax#3\relax
    #1#2,
  \else
    \dopermute{#1#2}#3\endmarker
    \recurse{#1}{#2}#3\endmarker
  \fi}
\newcommand*\permute[1]{\dopermute{}#1\endmarker}
\begin{document}
\noindent\raggedright
\permute{12345}
\end{document}

输出

注意\permute很挑剔,想要被喂食单个标记,所以\permute{12{34}}不会起作用,但\newcommand*\tf{34}\permute{12\tf}会起作用。(你真的想改变这样的事情吗?)

答案4

简单LaTeX代码,仅限 5 个字符:

\documentclass[10pt,a4paper]{article}
\usepackage[english]{babel}
\usepackage{pgffor}
\def\defPerm|#1#2#3#4#5|{\lccode`\1`#1\lccode`\2`#2\lccode`\3`#3\lccode`\4`#4\lccode`\5`#5}
\def\typePerm#1#2#3#4#5{\char\the\lccode`#1\char\the\lccode`#2\char\the\lccode`#3\char\the\lccode`#4\char\the\lccode`#5}%
\def\permuteV#1{{\defPerm|#1|\def\tmp{\foreach\next in {%
12345,12354,12435,12453,12534,12543,13245,13254,13425,13452,13524,13542,
14235,14253,14325,14352,14523,14532,15234,15243,15324,15342,15423,15432,
21345,21354,21435,21453,21534,21543,23145,23154,23415,23451,23514,23541,
24135,24153,24315,24351,24513,24531,25134,25143,25314,25341,25413,25431,
31245,31254,31425,31452,31524,31542,32145,32154,32415,32451,32514,32541,
34125,34152,34215,34251,34512,34521,35124,35142,35214,35241,35412,35421,
41235,41253,41325,41352,41523,41532,42135,42153,42315,42351,42513,42531,
43125,43152,43215,43251,43512,43521,45123,45132,45213,45231,45312,45321,
51234,51243,51324,51342,51423,51432,52134,52143,52314,52341,52413,52431,
53124,53142,53214,53241,53412,53421,54123,54132,54213,54231,54312,54321}
{\expandafter\typePerm\next{} }}\tmp}}%
%
\begin{document}

\noindent\permuteV{suvat}

\noindent\permuteV{LaTeX}

\noindent\texttt{\permuteV{@1234}}

\end{document}

在此处输入图片描述

相关内容