我想随机化枚举项的顺序(我知道有解决方案),但我还想修复其中一个条目。换句话说,我想随机化数字 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}