% The following is taken from \cite{Numerical Recipes in C}.
% The resulting MAX_RAND = 259199
% Proven good statistics but designed for speed.
% Added 8 entry shuffle (32 seemed a bit much).
%
% Output through LaTeX counter rand (or macro \rand).
%
% \randinit required for initialization
% \setrand{n} outputs rand between 0 and (n-1)
% \nextrand uses same scale computed by last \setrand

\newcount\rand@dum
\newcount\rand@m
\newcount\rand@a
\newcount\rand@c
\rand@m = 259200
\rand@a = 7141
\rand@c = 54773

\newcount\rand@temp

\def\step@rand{% computes next value for \rand@dum (internal only)
 \global\multiply\rand@dum by\rand@a
 \global\advance\rand@dum by\rand@c
 \rand@temp = \rand@dum% compute \rand@dum mod 259200
 \divide\rand@temp by\rand@m
 \multiply\rand@temp by\rand@m
 \global\advance\rand@dum by -\rand@temp
}

\newcounter{rand@k}% used by shuffle@rand

\newcount\rand@shuffle
\rand@shuffle = 32400
\newcount\rand@A
\newcount\rand@B
\newcount\rand@C
\newcount\rand@D
\newcount\rand@E
\newcount\rand@F
\newcount\rand@G
\newcount\rand@H
\newcount\rand@hold

\def\shuffle@rand{% random shuffle (internal only)
 \step@rand
 \c@rand@k = \rand@dum
 \divide\c@rand@k by\rand@shuffle
 \advance\c@rand@k by\@ne
 \global\rand = \csname rand@\Alph{rand@k}\endcsname
 \global\csname rand@\Alph{rand@k}\endcsname = \rand@hold
 \global\rand@hold = \rand@dum
}

\newcount\rand@s% used to scale rand
\rand@s = \@ne

%%%%%%%%%%%%%%%%%%%%%%%% start of user macros %%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcounter{rand}% scaled random number
\newcount\rand% TeX counter version

\newcommand{\randinit}{% required to initialize PRNG
 \global\rand@dum = \day% seed uses number of minutes since start of month
 \global\multiply\rand@dum by 1440
 \global\advance\rand@dum by \time
 \step@rand% warmup
 \step@rand
 \step@rand
 \step@rand
 \global\rand@A = \rand@dum% fill shuffle array
 \step@rand
 \global\rand@B = \rand@dum
 \step@rand
 \global\rand@C = \rand@dum
 \step@rand
 \global\rand@D = \rand@dum
 \step@rand
 \global\rand@E = \rand@dum
 \step@rand
 \global\rand@F = \rand@dum
 \step@rand
 \global\rand@G = \rand@dum
 \step@rand
 \global\rand@H = \rand@dum
 \step@rand
 \global\rand@hold = \rand@dum
}

\newcommand{\setrand}[1]{% scales rand between 0 and (#1 -1)
 \global\rand@s = \@ne% To obtain unscaled numbers, use \setrand{0}
 \ifnum #1 > \z@ \ifnum #1 < \rand@m
   \global\rand@s = \rand@m% compute 259200/#1 rounded up
   \global\advance\rand@s by -\@ne
   \global\advance\rand@s by #1\relax
   \global\divide\rand@s by #1\relax
 \fi \fi
 \shuffle@rand
 \global\divide\rand by\rand@s
 \global\c@rand = \rand
}

\newcommand{\nextrand}{% uses same scale as before
 \shuffle@rand
 \global\divide\rand by\rand@s
 \global\c#rand = \rand
}

