在文件中多次随机列出姓名列表

在文件中多次随机列出姓名列表

我有一份名单,你说:

 \newcommand{\names}{Fred, Barry, Joe, Jack, Zach}

我只是想在我的文档中以随机顺序显示列表几次。

就像是:

Barry, Zach, Joe, Jack, Fred 一开始

Joe, Zach, Barry, Fred, Jack 靠近文档的中间。

我发现最接近的简单解决方案是使用包

\usepackage{probsoln}
\PSNrandseed{\time}

并在文档中调用:

\doforrandN{5}{\who}{\studentsnames}{ 
    \who
}

但问题是,每次编译只创建一次随机化的种子。因此,在我的文档中两次调用随机列表将得到两个相同的列表。还有其他简单的方法吗?

答案1

您可以使用 L3 及其\seq_shuffle:N功能。下面将其包装在一些方便的宏中:

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand \setNameList { m m }
  {
    \seq_clear_new:c { l__andrew_namelist_#1_seq }
    \seq_set_from_clist:cn { l__andrew_namelist_#1_seq } {#2}
  }
\msg_new:nnn { andrew } { unknown-list } { Unknown~ list~ #1 }
\NewDocumentCommand \useNameListShuffled { m O{,~} }
  {
    \seq_if_exist:cTF { l__andrew_namelist_#1_seq }
      {
        \group_begin:
          \seq_shuffle:c { l__andrew_namelist_#1_seq }
          \seq_use:cn { l__andrew_namelist_#1_seq } {#2}
        \group_end:
      }
      { \msg_error:nnn { andrew } { unknown-list } {#1} }
  }
\ExplSyntaxOff

\setNameList{names}{Fred, Barry, Joe, Jack, Zach}


\begin{document}
\useNameListShuffled{names}

\useNameListShuffled{names}[ and ]
\end{document}

答案2

这是(潜在的)糟糕的代码,但它能起作用(可能更多是出于偶然而非设计)。

\documentclass{article}

\usepackage{expl3}
\begin{document}

\ExplSyntaxOn


\clist_new:N \l__andrew_students
\clist_set:Nn \l__andrew_students{Zack, Barry, Fred, Jack, Joe}
\cs_new:Nn \print_students: {\clist_use:Nnnn \l__andrew_students {~and~} {,~} {,~ and~} }

\cs_new:Nn \randomise_students: {

        \clist_sort:Nn \l__andrew_students {
                \fp_compare:nNnTF {rand()} > {0.5}
                { \sort_return_swapped: }
                { \sort_return_same: }
        }

}

\cs_new_eq:NN \randomisestudents\randomise_students:
\cs_new_eq:NN \printstudents\print_students:

\ExplSyntaxOff

\printstudents
\randomisestudents

\printstudents

\randomisestudents
\printstudents

\end{document}

设置初始列表可能需要另一个命令,这取决于您需要更改列表的次数。

编辑:我现在有更多的时间,所以做一点解释。

我选择了clist而不是seq(像@Skillmon 的答案),但它们的行为(至少从用户的角度来看)非常相似(在我测试的版本上)。我确实查看了interface3.pdf“shuffle”,但没有找到。我怀疑这是由于安装时间太长造成的 - 它是我的(不是全新的)Linux 包管理器提供的(我认为它是 TeX Live 2018,但我现在不在那台电脑上)。但我可以看到(在更现代的 TeX Live 上)seq有 shuffle,但clist没有。

我对风格做了一些修改,但我认为它仍然不是很棒。

代码解释:

  • \clist_set:Nn将命名变量设置为提供的逗号分隔列表
  • 排序算法根据随机浮点数(从 0 到 1)是否大于 .5(而不是列表的固有特征)来决定交换列表的两个成员
  • \clist_use:Nnnn在项目之间打印逗号(最后两个除外,它们将是一个逗号和单词“and”)
  • 此版本将保持顺序,除非调用,这与其他答案略有不同。这可以通过在方法中\randomisestudents调用来更改(在之前或之后)\randomise_students:\print_students:clist_use

正如@DavidCarlisle提到的那样,如果排序算法假设然后,rand > 0.5则在排序中使用可能会导致排序永不终止。 因此,除了一次性项目外,我不会将此方法或代码用于任何其他项目,在一次性项目中,如果它看起来不会终止,我可以停止运行并重新启动。a>bb>ca>c

因为它在测试期间发挥了作用,所以我没有过多考虑潜在的陷阱。

相关内容