随机枚举但修复一个条目

随机枚举但修复一个条目

我想随机化枚举项的顺序(我知道有解决方案),但我还想修复其中一个条目。换句话说,我想随机化数字 1-10,但让 6 位于第 6 位。有解决方案吗?

编辑:我正在使用的代码来自随机随机排序

\documentclass[12pt]{article}  
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{listings}
\usepackage{enumitem}

\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

\lstset{
basicstyle=\bfseries\scriptsize\tt,
}

\begin{document}
\LARGE
\begin{center}
    Do the following give categorical, discrete, or continuous responses?
\end{center}
\begin{randomList}
    \item 1

    \item 2

    \item 3

    \item 4

    \item 5

    \item 6

    \item 7

    \item 8

    \item 9

    \item 10

\end{randomList}
\end{document}

答案1

好的,我已经修改了上一篇文章中的代码,以允许环境\fixedItem中出现 a randomList。原始代码的想法是,当环境打开时,-thk定义\item一个内部宏\randomListItem@<k>,然后在环境关闭时以随机顺序打印出这些宏。新宏\fixedItem定义一个内部宏\fixedItem@<k>,如果存在,则在步骤中打印k。这破坏了以前代码的一些“优雅”,因为我必须在几个地方添加额外的计数器,但这还不算太糟:)

在新版本中,代码片段

\begin{randomList}
    \item 1

    \item 2

    \item 3

    \fixedItem 4 fixed!

    \item 5

    \fixedItem 6 fixed!

    \fixedItem 7 fixed

    \item 8

    \item 9

    \fixedItem 10 fixed!

    \fixedItem 11 fixed!

\end{randomList}

将生成(根据 pgf 种子最多为一个随机排列)列表:

在此处输入图片描述

你可以拥有任意多个固定项目,它们可以出现在列表中的任何位置。就像我之前的代码一样随机列表环境, 你\item每个块末尾都需要有一个空行 ,包括最后一个。该代码可与任何枚举类环境一起使用,包括使用枚举项包。有关详细信息,请参阅我之前的解决方案。

完整代码如下:

\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
\newcounter{randomListItemLength}%  number of items in the random list used to construct \randomListItem@<k>'s

% \useRandomItem{k} prints item number k
\newcommand\useRandomItem[1]{%
  \stepcounter{randomListCounter}%
  \printFixedItemIfItExists\csname randomListItem@#1\endcsname%
}
\newcommand\printFixedItemIfItExists{% prints fixedItem@<randomListCounter>} if it exits and increments the counter
  \expandafter\ifcsdef\expandafter{fixedItem@\therandomListCounter}{% insert fixed item
        \expandafter\csname fixedItem@\therandomListCounter\endcsname\stepcounter{randomListCounter}}{}%
  \expandafter\ifcsdef\expandafter{fixedItem@\therandomListCounter}{\printFixedItemIfItExists}{}% checked fixed item
}

% \setRandomItem{k} saves item number k for future use
% and builds a random permutation at the same time
\def\setRandomItem#1\par{\stepcounter{randomListCounter}\stepcounter{randomListItemLength}%
       \expandafter\protected@xdef\csname randomListItem@\therandomListCounter\endcsname{\noexpand\item#1}%
       \randomlyInsertInList{randomlyOrderedList}{\therandomListItemLength}{\therandomListCounter}
}%

% \fixedItem{k} saves item number k for future use
% and builds a random permutation at the same time
\def\fixedItem#1\par{\stepcounter{randomListCounter}%
   \expandafter\protected@xdef\csname fixedItem@\therandomListCounter\endcsname{\noexpand\item#1}%
}

\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
  % Nothing 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
    \stepcounter{randomListCounter}% check for print fixed items at the end
    \printFixedItemIfItExists%
  \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}
    \item 1

    \item 2

    \item 3

    \fixedItem 4 fixed!

    \item 5

    \fixedItem 6 fixed!

    \fixedItem 7 fixed

    \item 8

    \item 9

    \fixedItem 10 fixed!

    \fixedItem 11 fixed!

\end{randomList}

\end{document}

相关内容