Here's a version with xparse
and LaTeX3 code, with the help of the random.tex
file by D. Arsenau
\documentclass{article}
\usepackage{xparse}
\input{random}
\ExplSyntaxOn
\NewDocumentCommand{\htguse}{ m }
{
\use:c { htg_arg_#1: }
}
\NewDocumentCommand{\selectNrandom}{ m m m }
{
\htg_select_n_random:nnn { #1 } { #2 } { #3 }
}
\cs_new_protected:Npn \htg_select_n_random:nnn #1 #2 #3
{
\seq_clear:N \l_htg_used_seq
\int_set:Nn \l_htg_length_int { \clist_count:n { #2 } }
\int_compare:nTF { #1 > \l_htg_length_int }
{
\msg_error:nnxx { randomchoice } { too-many } { #1 } { \int_to_arabic:n { \l_htg_length_int } }
}
{
\int_step_inline:nnnn { 1 } { 1 } { #1 }
{
\htg_get_random:
\cs_set:cpx { htg_arg_##1: }
{ \clist_item:nn { #2 } { \l_htg_random_int } }
}
#3
}
}
\cs_new_protected:Npn \htg_get_random:
{
\setrannum { \l_htg_random_int } { 1 } { \l_htg_length_int }
\seq_if_in:NxTF \l_htg_used_seq { \int_to_arabic:n { \l_htg_random_int } }
{ \htg_get_random: }
{ \seq_put_right:Nx \l_htg_used_seq { \int_to_arabic:n { \l_htg_random_int } } }
}
\seq_new:N \l_htg_used_seq
\int_new:N \l_htg_length_int
\int_new:N \l_htg_random_int
\msg_new:nnnn { randomchoice } { too-many }
{ Too~ many~choices }
{ You~want~to~select~#1~elements,~but~you~have~only~#2 }
\ExplSyntaxOff
\begin{document}
\selectNrandom{2}
{N, W, Z, Q, R, C}
{$\mathbf{\htguse{1}}$ and $\mathbf{\htguse{2}}$}
\selectNrandom{3}
{A, B, C}
{$\mathbf{\htguse{1}}$, $\mathbf{\htguse{2}}$ and $\mathbf{\htguse{3}}$}
\selectNrandom{3}
{N, W}
{$\mathbf{\htguse{1}}$, $\mathbf{\htguse{2}}$ and $\mathbf{\htguse{3}}$}
\end{document}
The macros take care to check that distinct elements are chosen by maintaining the list of already extracted elements and doing a new choice if a number is extracted again.
You refer to the first, second, and so on, element by \htguse{1}
, \htguse{2}
and so on.
The third call will raise an error:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! randomchoice error: "too-many"
!
! Too many choices
!
! See the randomchoice documentation for further information.
!
! For immediate help type H <return>.
!...............................................
l.56 ...bf{\htguse{2}}$ and $\mathbf{\htguse{3}}$}
? h
|'''''''''''''''''''''''''''''''''''''''''''''''
| You want to select 3 elements, but you have only 2
|...............................................
With a recent expl3
kernel, \input{random}
is not needed any longer with pdflatex
or LuaLaTeX (it still is necessary for XeLaTeX). The line
\setrannum { \l_htg_random_int } { 1 } { \l_htg_length_int }
can be substituted with
\int_set:Nn \l_htg_random_int { \fp_eval:n { randint( \l_htg_length_int ) } }