答案1
我需要一个列表,其中数字 1、2、...、52 随机排列 - 但不重复!
您需要进行随机播放。一个已实现的随机播放宏是\seq_shuffle:N
from expl3
。因此,此答案提供了一个非pgffor
解决方案:
\documentclass{article}
\ExplSyntaxOn
\seq_clear:N \l_tmpa_seq
\clist_map_inline:nn { $\clubsuit$, $\diamondsuit$, $\heartsuit$, $\spadesuit$ }
{
\int_step_inline:nnn {1} {14}
{ \seq_put_right:Nn \l_tmpa_seq {#1##1} }
}
\seq_new:N \c_cards_seq
\seq_set_eq:NN \c_cards_seq \l_tmpa_seq
\tl_new:N \l_card_tl
\tl_new:N \l_card_count_tl
\cs_new_protected:Nn \cards_new:N
{
\seq_new:N #1
\seq_set_eq:NN #1 \c_cards_seq
}
\cs_new_protected:Nn \cards_shuffle:N
{ \seq_shuffle:N #1 }
\cs_new_protected:Nn \cards_take_n:Nnn
{
\int_step_variable:nnNn {1} {#2} \l_card_count_tl
{
\seq_pop_left:NN #1 \l_card_tl
#3
}
}
\ExplSyntaxOff
\begin{document}
\parindent=0pt
\ExplSyntaxOn
\cards_new:N \l_cards_tmpa_seq
\cards_shuffle:N \l_cards_tmpa_seq
\cards_take_n:Nnn \l_cards_tmpa_seq {12}
{ No\l_card_count_tl. ~ \l_card_tl \\ }
\ExplSyntaxOff
\end{document}
一种可能的输出
更新部分改组
这与 John Kormylo 的答案非常相似https://tex.stackexchange.com/a/346285,仅调用部分洗牌。
\documentclass{article}
\usepackage{pgffor}
\usepackage{etoolbox}
% init n items
\newcommand\initCards[1]{%
\foreach \i in {1,...,#1} {%
\csxdef{shuffle@\i}{\i}%
}%
}
% shuffle and use the first m items, m <= n
\newcommand\getRandomN[2]{% #1 = m, #2 = n
\foreach \i in {1,...,#1} {% % for i in 1..12
\pgfmathparse{random(\i,#2)}% % for j in random(i, 12)
\letcs\tempa{shuffle@\i}% % exchange a[i] and a[j]
\global\csletcs{shuffle@\i}{shuffle@\pgfmathresult}%
\global\cslet{shuffle@\pgfmathresult}\tempa
No\i. \csuse{shuffle@\i}\\ % use a[i]
}
}
\begin{document}
\parindent=0pt
\pgfmathsetseed{125}
\initCards{12}
\getRandomN{12}{12}
\end{document}
答案2
这是直接、手动的方法。尝试从重复系列中创建不带重复的系列是一种折磨。除非你有时间,否则不要尝试:R 就是为此而生的。
使用我的代码需要:
- 复制粘贴
创建其他示例所需的内容:
- 在你的系统上安装 R,除非你已经
- 例如以命令行/终端 (Rterm) 形式运行 R
n<-sample(1:52,52,replace=F); paste(n,collapse=",")
- 从那里复制:
[1] "48,20,50,26,1,6,30,17,22, ..."
解码:
n<-sample(1:52,52,replace=F)
从范围 1:52 创建 52 个不重复的样本,并将其存储在n
(作为列表)中paste(n,collapse=",")
插入,
在中间,因为这是 tikz 喜欢的(1,2,3
而不是1 2 3
)
在你的 Latex 环境中运行...
您将需要软件包iexec
和shellesc
。请参阅其文档。
也可以看看标签 r在这个网站上。
代码的作用:
- 常规
\foreach
命令,通过计数变量[count=\i]
(列表内的索引)进行增强 - 画一些水平笔画
\draw (\i,\r) -- +(2,0);
- 请注意样本数量的均匀分布
\documentclass[10pt,border=1cm,tikz]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \r [count=\i] in { 48,20,50,26,1,6,30,17,22,8,42,35,45,21,39,44,49,7,31,40,19,47,3,18,5,12,52,38,13,41,15,9,16,29,27,43,37,23,4,51,32,36,25,28,34,10,24,14,46,33,11,2}
\draw (\i,\r) -- +(2,0);
\end{tikzpicture}
\end{document}
From Rterm:
> n<-sample(1:52,52,replace=F); paste(n,collapse=",")
[1] "48,20,50,26,1,6,30,17,22,8,42,35,45,21,39,44,49,7,31,40,19,47,3,18,5,12,52,38,13,41,15,9,16,29,27,43,37,23,4,51,32,36,25,28,34,10,24,14,46,33,11,2"