将某项标记为“随机枚举”

将某项标记为“随机枚举”

我从以下代码获得随机随机排序

如何标记(类似 \label{1}, \ref{1})特定的 randomList 项以在文档末尾打印相应的字母?

\documentclass{article}
\usepackage{etoolbox}
\usepackage{pgfkeys}
\usepackage{pgfmath}

% code for generating a random permutation
\newcounter{randomListLength}%   current length of our random list
\newcounter{randomListPosition}% current list index
\newcounter{newRandomListElementPosition}% position to insert new element
% insert #1 into the next position of \newRandomList unless the position
% index \randomListPosition is equal to \newRandomListElementPosition in
% which case the \newRandomListElement is added first
\newcommand\randomlyInsertElement[1]{%
  \stepcounter{randomListPosition}%
  \ifnum\value{randomListPosition}=\value{newRandomListElementPosition}%
    \listxadd\newRandomList{\newRandomListElement}%
  \fi%
  \listxadd\newRandomList{#1}%
}
% \randomlyInsertInList{list name}{new list length}{new element}
\newcommand\randomlyInsertInList[3]{%
  \pgfmathparse{random(1,#2)}%
  \setcounter{newRandomListElementPosition}{\pgfmathresult}%
  \ifnum\value{newRandomListElementPosition}=#2\relax%
    \listcsxadd{#1}{#3}%
  \else%
    \def\newRandomList{}% start with an empty list
    \def\newRandomListElement{#3}% and the element that we need to add
    \setcounter{randomListPosition}{0}% starting from position 0
    \xdef\currentList{\csuse{#1}}
    \forlistloop\randomlyInsertElement\currentList%
    \csxdef{#1}{\newRandomList}%
  \fi%
}

% define some pgfkeys to allow key-value arguments
\pgfkeys{/randomList/.is family, /randomList,
  environment/.code = {\global\letcs\beginRandomListEnvironment{#1}
                       \global\letcs\endRandomListEnvironment{end#1}
                      },
  enumerate/.style = {environment=enumerate},
  itemize/.style = {environment=itemize},
  description/.style = {environment=description},
  seed/.code = {\pgfmathsetseed{#1}}
}
\pgfkeys{/randomList, enumerate}% enumerate is the default

% finally, the code to construct the randomly permuted list
\makeatletter
\newcounter{randomListCounter}% for constructing \randomListItem@<k>'s

% \useRandomItem{k} prints item number k
\newcommand\useRandomItem[1]{\csname randomListItem@#1\endcsname}

% \setRandomItem{k} saves item number k for future use
% and builds a random permutation at the same time
\def\setRandomItem#1\par{\stepcounter{randomListCounter}%
       \expandafter\protected@xdef\csname randomListItem@\therandomListCounter\endcsname{\noexpand\item#1}%
       \randomlyInsertInList{randomlyOrderedList}{\therandomListCounter}{\therandomListCounter}%
}%
\let\realitem=\item
\makeatother
\newenvironment{randomList}[1][]{% optional argument -> pgfkeys
  \pgfkeys{/randomList, #1}% process optional arguments
  \setcounter{randomListLength}{0}% initialise length of random list
  \def\randomlyOrderedList{}% initialise the random list of items
  % Nthing is printed in the main environment. Instead, \item is
  % used to slurp the "contents" of the item into randomListItem@<counter>
  \let\item\setRandomItem%      
}
{% now construct the list environment by looping over the randomly ordered list
  \let\item\realitem
  \setcounter{randomListCounter}{0}
  \beginRandomListEnvironment\relax
    \forlistloop\useRandomItem\randomlyOrderedList
  \endRandomListEnvironment
}

% test compatibility with enumitem
\usepackage{enumitem}
\newlist{Testlist}{enumerate}{1} %
\setlist[Testlist]{label*=\alph*.}
\setlist{nosep}\parindent=0pt% for more compact output

\begin{document}


  \begin{randomList}[environment=Testlist, seed=4]
    \item First item

    \item Second item

    \item Third item

  \end{randomList}


\end{document}

答案1

必须使用固定种子,否则参考将会从一次运行变为另一次运行。

\documentclass{article}
\usepackage{xparse,environ,enumitem}

\ExplSyntaxOn
\NewEnviron{randomList}[1][]
 {
  \keys_set:nn { lucas/randomlist } { #1 }
  \seq_set_split:NnV \l__lucas_randomlist_items_seq { \item } \BODY
  % discard the empty first item
  \seq_pop_left:NN \l__lucas_randomlist_items_seq \l_tmpa_tl
  \seq_shuffle:N \l__lucas_randomlist_items_seq
  \begin{\l__lucas_randomlist_env_tl}
  \item \seq_use:Nn \l__lucas_randomlist_items_seq { \item }
  \end{\l__lucas_randomlist_env_tl}
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { NnV }
\keys_define:nn { lucas/randomlist }
 {
  environment .tl_set:N = \l__lucas_randomlist_env_tl,
  seed .code:n = \sys_gset_rand_seed:n { #1 },
 }
\ExplSyntaxOff

\newlist{Testlist}{enumerate}{1} %
\setlist[Testlist]{label*=\alph*.}
\setlist{nosep}\parindent=0pt% for more compact output

\begin{document}


\begin{randomList}[environment=Testlist, seed=4]
\item\label{1} First item

\item Second item

\item Third item
\end{randomList}

\ref{1}

\end{document}

在此处输入图片描述

您还可以制作答案,只要它晚于练习即可。

\documentclass{article}
\usepackage{xparse,environ,enumitem}

\ExplSyntaxOn
\NewEnviron{randomList}[1][]
 {
  \keys_set:nn { lucas/randomlist } { #1 }
  \lucas_randomlist:V \BODY
 }
\NewDocumentCommand{\answerkey}{}
 {
  \subsubsection*{Answer ~ key}
  \begin{enumerate}[nosep]
  \seq_map_inline:Nn \g_lucas_randomlist_answers_seq { \item ##1 }
  \end{enumerate}
 }
\NewDocumentCommand{\correct}{}
 {
  \seq_gput_right:Nx \g_lucas_randomlist_answers_seq { \use:c { @currentlabel } }
 }

\keys_define:nn { lucas/randomlist }
 {
  environment .tl_set:N = \l__lucas_randomlist_env_tl,
  seed .code:n = \sys_gset_rand_seed:n { #1 },
 }

\seq_new:N \g_lucas_randomlist_answers_seq
\cs_new_protected:Nn \lucas_randomlist:n
 {
  \seq_set_split:Nnn \l__lucas_randomlist_items_seq { \item } { #1 }
  % discard the empty first item
  \seq_pop_left:NN \l__lucas_randomlist_items_seq \l_tmpa_tl
  \seq_shuffle:N \l__lucas_randomlist_items_seq
  \begin{\l__lucas_randomlist_env_tl}
  \item \seq_use:Nn \l__lucas_randomlist_items_seq { \item }
  \end{\l__lucas_randomlist_env_tl}
 }
\cs_generate_variant:Nn \lucas_randomlist:n { V }

\ExplSyntaxOff

\newlist{Testlist}{enumerate}{1}
\setlist[Testlist]{label*=\alph*.}
\setlist{nosep}\parindent=0pt% for more compact output

\begin{document}

\begin{enumerate} % outer list of exercises

\item First exercise
  \begin{randomList}[environment=Testlist]
  \item\correct First item

  \item Second item

  \item Third item
  \end{randomList}

\item Second exercise
  \begin{randomList}[environment=Testlist]
  \item First item

  \item\correct Second item

  \item Third item
  \end{randomList}

\item Third exercise
  \begin{randomList}[environment=Testlist]
  \item\correct First item

  \item Second item

  \item Third item
  \end{randomList}

\end{enumerate}

\answerkey

\end{document}

在此处输入图片描述

相关内容