% Author : C. Pierquet % licence : Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txtf \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{randintlist}[2024/09/24 0.1.1 Create a list of random numbers with or without multiple values] %------History % 0.1.1 Possibility to exclude values % 0.1.0 Initial version %------Packages \RequirePackage{simplekv} \RequirePackage{listofitems} \RequirePackage{randomlist} \RequirePackage{xintexpr} \RequirePackage{xstring} \RequirePackage{ifthen} %-----Macros (latex3) for sorting and seed \ExplSyntaxOn \cs_new_eq:NN \randintseed \sys_gset_rand_seed:n \NewDocumentCommand\intascsortlist{m} { \clist_sort:Nn #1 { \fp_compare:nNnTF {##1} > {##2} { \sort_return_swapped: } { \sort_return_same: } } } \NewDocumentCommand\intdessortlist{m} { \clist_sort:Nn #1 { \fp_compare:nNnTF {##1} < {##2} { \sort_return_swapped: } { \sort_return_same: } } } \ExplSyntaxOff %----Internal macro (latex2) for testing if element is in list \newcommand\ifintvalueinlist[2]{\IfSubStr{,#2,}{,#1,}} \newcommand\boolvalueinlist[2]{\IfSubStr{,#2,}{,#1,}{\def\resisinlist{1}}{\def\resisinlist{0}}} \newcommand\xintifintvalueinlist[4]{% \IfSubStr{,#2,}{,#1,}{\xdef\RESTMPVALUE{1}}{\xdef\RESTMPVALUE{0}}% \xintifboolexpr{ \RESTMPVALUE == 1}{#3}{#4}% } %----Macro for generating \defKV[randomlistintegers]{% min=\def\TAEEmin{#1},% max=\def\TAEEmax{#1},% nb=\def\TAEEnb{#1},% sep=\def\TAEEsep{#1},% sort=\def\TAEEtri{#1},% seed=\def\TAEEseed{#1},% exclude=\def\TAEEexcluded{#1} } \setKVdefault[randomlistintegers]{% min=1,% max=50,% nb=6,% sep={,},% sort=no,% repeat=false,% seed={-},% exclude={} } \NewList{tmprandintlist} \NewDocumentCommand\randintlist{ O{} m }{%1=keys,2=listname \useKVdefault[randomlistintegers]% \setKV[randomlistintegers]{#1}% \ifboolKV[randomlistintegers]{repeat}%repeat or not {%repeat allowed \IfStrEq{\TAEEseed}{-}% {}% {% \randintseed{\TAEEseed}% }% %list creation of first element \def\resisinlist{1}% \whiledo{\resisinlist=1}{% \xdef\tmpresrandint{\fpeval{randint(\TAEEmin,\TAEEmax)}}% \boolvalueinlist{\tmpresrandint}{\TAEEexcluded}% }% \xdef#2{\tmpresrandint}% %list creation of other elements \xintFor* ##1 in {\xintSeq{2}{\TAEEnb}}% \do{% \def\resisinlist{1}% \whiledo{\resisinlist=1}{% \xdef\tmpresrandint{\fpeval{randint(\TAEEmin,\TAEEmax)}}% \boolvalueinlist{\tmpresrandint}{\TAEEexcluded}% }% \xdef#2{#2,\tmpresrandint}% }% }% {%no repeating %randomize numbers \IfStrEq{\TAEEseed}{-}% {}% {% \RLsetrandomseed{\TAEEseed}% }% \ClearList{tmprandintlist}%clearing the list \xintFor* ##1 in {\xintSeq{\TAEEmin}{\TAEEmax}}% \do{% \ifintvalueinlist{##1}{\TAEEexcluded}% {}% {% \InsertRandomItem{tmprandintlist}{##1}% }% }% %list creation (first then other) \xdef#2{\tmprandintlist[0]}% \xintFor* ##1 in {\xintSeq{1}{\TAEEnb-1}}% \do{% \xdef#2{#2,\tmprandintlist[##1]}% }% }% %sorting \IfStrEq{\TAEEtri}{asc}%if ascending {\intascsortlist{#2}}% {}% \IfStrEq{\TAEEtri}{des}%if descending {\intdessortlist{#2}}% {}% \StrSubstitute{#2}{,}{\TAEEsep}[#2]%swipping separator if necessary } %-----Macro for extracting \NewDocumentCommand\getitemfromrandintlist{ O{,} m m }{% \IfEq{#1}{/}% {% \setsepchar[.]{#1}% }% {% \setsepchar{#1}% }% \readlist*\TMPLISTRANDINT{#2}% \TMPLISTRANDINT[#3]% } %-----french version \defKV[randomlisteentiers]{% Min=\def\TAEEmin{#1},% Max=\def\TAEEmax{#1},% Nb=\def\TAEEnb{#1},% Sep=\def\TAEEsep{#1},% Tri=\def\TAEEtri{#1},% Graine=\def\TAEEseed{#1},% Exclure=\def\TAEEexcluded{#1} } \setKVdefault[randomlisteentiers]{% Min=1,% Max=50,% Nb=6,% Sep={,},% Tri=non,% Repet=false,% Graine={-},% Exclure={} } \NewDocumentCommand\ListeRandint{ O{} m }{%1=keys,2=listname \useKVdefault[randomlisteentiers]% \setKV[randomlisteentiers]{#1}% \ifboolKV[randomlisteentiers]{Repet}%repeat or not {%repeat allowed \IfStrEq{\TAEEseed}{-}% {}% {% \randintseed{\TAEEseed}% }% %list creation of first element \def\resisinlist{1}% \whiledo{\resisinlist=1}{% \xdef\tmpresrandint{\fpeval{randint(\TAEEmin,\TAEEmax)}}% \boolvalueinlist{\tmpresrandint}{\TAEEexcluded}% }% \xdef#2{\tmpresrandint}% %list creation of other elements \xintFor* ##1 in {\xintSeq{2}{\TAEEnb}}% \do{% \def\resisinlist{1}% \whiledo{\resisinlist=1}{% \xdef\tmpresrandint{\fpeval{randint(\TAEEmin,\TAEEmax)}}% \boolvalueinlist{\tmpresrandint}{\TAEEexcluded}% }% \xdef#2{#2,\tmpresrandint}% }% }% {%no repeating %randomize numbers \IfStrEq{\TAEEseed}{-}% {}% {% \RLsetrandomseed{\TAEEseed}% }% \ClearList{tmprandintlist}%clearing the list \xintFor* ##1 in {\xintSeq{\TAEEmin}{\TAEEmax}}% \do{% \ifintvalueinlist{##1}{\TAEEexcluded}% {}% {% \InsertRandomItem{tmprandintlist}{##1}% }% }% %list creation (first then other) \xdef#2{\tmprandintlist[0]}% \xintFor* ##1 in {\xintSeq{1}{\TAEEnb-1}}% \do{% \xdef#2{#2,\tmprandintlist[##1]}% }% }% %sorting \IfStrEq{\TAEEtri}{croiss}%if ascending {\intascsortlist{#2}}% {}% \IfStrEq{\TAEEtri}{decroiss}%if descending {\intdessortlist{#2}}% {}% \StrSubstitute{#2}{,}{\TAEEsep}[#2]%swipping separator if necessary } %-----Macro for extracting \NewDocumentCommand\ExtraireEltListeRandint{ O{,} m m }{% \IfEq{#1}{/}% {% \setsepchar[.]{#1}% }% {% \setsepchar{#1}% }% \readlist*\TMPLISTRANDINT{#2}% \TMPLISTRANDINT[#3]% } \endinput