Qualcosa del genere?
…
Spiegazione.
`\g@addto@macro\r@nd{\global\cr@nd\cr@nd}`
Per motivi di implementazione, il comando \rand non funziona se chiamato dentro un gruppo. Così si risolve.
`\newcommand{\rchoice}[4][]{\begingroup
\ifx\relax#1\relax
\reinitrand[first=#2,last=#3]%
\else
\reinitrand[seed=#1,first=#2,last=#3]%
\fi`
Il comando \rchoice ha tre argomenti obbligatori: il minimo, il massimo e la lista dei numeri da escludere. Per prima cosa inizializziamo il contatore dei numeri casuali; l’argomento opzionale è il seme. Ci mettiamo in un gruppo.
` \def\xyz@{}%
\def\excl@list{#4}%
\@for\next:=\excl@list\do{\@namedef{xyz@\romannumeral\next}{}}%`
Per ogni elemento della lista di esclusione, che deve essere un numero, definiamo il comando \xyz@xii (se il numero è 12). Così possiamo sapere se il numero è fra gli esclusi o fra quelli già estratti, esaminando se \xyz@xii (o quello che è) è definito.
` \count\z@=\z@
\@rchoice\endgroup}`
Avviamo la ricorsione, tenendo conto di quanti numeri abbiamo estratto nel contatore 0 (tanto siamo in un gruppo).
`\def\@rchoice{%
\ifnum\count\z@=10 \else
\expandafter\@dochoice
\fi}`
La macro \@rchoice è quella responsabile della ricorsione. Se abbiamo già raggiunto il numero di 10 estrazioni buone, abbiamo finito, altrimenti eseguiamo \@dochoice.
`\def\@dochoice{\rand
\@ifundefined{xyz@\romannumeral\c@rand}{\@goodchoice}{\@rchoice}}`
La macro \@dochoice estrae un numero; se il numero è fra quelli esclusi o già estratti, eseguiamo ancora \@rchoice. Altrimenti eseguiamo \@goodchoice.
`\def\@goodchoice{\@namedef{xyz@\romannumeral\c@rand}{}%
\advance\count\z@\@ne\number\c@rand\relax\space\@rchoice}`
La macro \@goodchoice definisce \xyz@xii (se il numero estratto è 12) o il comando opportuno. Poi avanza il contatore della ricorsione, stampa il numero estratto ed esegue di nuovo \@rchoice.
Ciao
Enrico