# \rand inside \forloop creates identical values

I try to create a table with random entries... By browsing the tag, I found some help on random number generators and I tried using lcg.

Surprisingly I seem to create the same random number over and over again, whatever I choose as seed... does anyone have a clue?

Code for a 5x5 table:

\chgrand[first=0, last=4, counter=kids]
\begin{tabular}{rrrrr}
\forloop{row_number}{1}{\value{row_number} < 6}{%%
\forloop{col_number}{1}{\value{col_number} < 5}{%%%
\rand\arabic{kids} &
}%%%
\rand\arabic{kids}
\\ }%%
\end{tabular}


creates:

4 4 4 4 4
4 4 4 4 4
4 4 4 4 4
4 4 4 4 4
4 4 4 4 4


doesn't look random to me...

I tried changing \rand to \rand\rand and all entries changed to '3'. So I presume every time I call \rand it starts back from the same seed, but I don't see why, as the seed is declared before the \forloop. Or isn't it?

• This seems appropriate, while looking for an answer dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/… – egreg Oct 24 '12 at 21:22
• Probably your \forloop puts a group around the body. Package lcg uses local assignments, thus the internal state is reset after the group. – Heiko Oberdiek Oct 24 '12 at 21:28
• i could add something like \chgrand[seed=\value{rand}] inside the \forloop, but that hardly seems a workaround to me (i guess that would lead to the same re-occuring sequence over and over again) – long tom Oct 24 '12 at 21:28
• @HeikoOberdiek: so i'd have to change to \foreach? or to another random number generator? – long tom Oct 24 '12 at 21:30
• \foreach of pgf also puts a group around the loop body. – Heiko Oberdiek Oct 24 '12 at 21:32

The problem is that you're doing that inside a table cell and TeX doesn't like it very much. It's better to build up the token list before doing the table:

\documentclass{article}
\usepackage{lcg,forloop}
\newtoks\dierckxtoks
\newcounter{row_number}\newcounter{col_number}

\begin{document}

\chgrand[first=0, last=4, counter=kids]
\dierckxtoks={}

\forloop{row_number}{1}{\value{row_number} < 6}{%
\forloop{col_number}{1}{\value{col_number} < 5}{%
\rand
\edef\x{\the\dierckxtoks\arabic{kids} &}
\dierckxtoks\expandafter{\x}%
}%
\rand
\edef\x{\the\dierckxtoks\arabic{kids} \noexpand\\}
\dierckxtoks\expandafter{\x}%
}

\begin{tabular}{rrrrr}
\the\dierckxtoks
\end{tabular}

\end{document}


On the other hand, as shown in my first comment, also 444444444 can be a sequence of random numbers. :-)

### The mandatory expl3 solution.

\documentclass{article}
\usepackage{lcg}
\newcounter{randnumb}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\randomtabular}{ O{randnumb} m m m m }
% #1 = counter name (optional default randnumb)
% #2 = lowest value
% #3 = highest value
% #4 = rows
% #5 = columns
{
\chgrand[first=#2, last=#3, counter=#1]
\dierckx_random_tabular:nnn {#1}{#4}{#5}
}
\tl_new:N \l_dierckx_tabular_tl
\cs_new_protected:Npn \dierckx_random_tabular:nnn #1 #2 #3
{
\tl_clear:N \l_dierckx_tabular_tl
\prg_replicate:nn { #2 }
{
\prg_replicate:nn { #3 - 1 }
{
\rand
\tl_put_right:Nx \l_dierckx_tabular_tl { \arabic{#1} & }
}
\rand
\tl_put_right:Nx \l_dierckx_tabular_tl { \arabic{#1} }
\tl_put_right:Nn \l_dierckx_tabular_tl { \\ }
}
\begin{tabular}{*{#3}{r}}
\l_dierckx_tabular_tl
\end{tabular}
}
\ExplSyntaxOff

\begin{document}

\randomtabular{0}{9}{6}{4}

\randomtabular[kids]{0}{4}{5}{5}

\end{document}


A different solution using the random number facility of pgf:

\documentclass{article}
\usepackage{pgf}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\randomtabular}{ m m m m }
% #1 = lowest value
% #2 = highest value
% #3 = rows
% #4 = columns
{
\dierckx_random_tabular:nnnn {#1}{#2}{#3}{#4}
}
\tl_new:N \l__dierckx_tabular_tl
\int_new:N \l__dierckx_random_number_int
\cs_new_protected:Npn \dierckx_random_tabular:nnnn #1 #2 #3 #4
{
\tl_clear:N \l_dierckx_tabular_tl
\prg_replicate:nn { #3 }
{
\prg_replicate:nn { #4 - 1 }
{
\dierckx_get_rand:nn { #1 } { #2 }
\tl_put_right:Nx \l_dierckx_tabular_tl { \int_to_arabic:n { \l__dierckx_random_number_int } & }
}
\dierckx_get_rand:nn { #1 } { #2 }
\tl_put_right:Nx \l_dierckx_tabular_tl { \int_to_arabic:n { \l__dierckx_random_number_int } }
\tl_put_right:Nn \l_dierckx_tabular_tl { \\ }
}
\begin{tabular}{*{#3}{r}}
\l_dierckx_tabular_tl
\end{tabular}
}
\cs_new_protected:Npn \dierckx_get_rand:nn #1 #2
{
\pgfmathrandominteger{ \l__dierckx_random_number_int } { #1 } { #2 }
}
\ExplSyntaxOff

\begin{document}

\randomtabular{0}{9}{6}{4}

\bigskip

\randomtabular{0}{4}{5}{5}

\end{document}


There is no optional argument any more, but it doesn't seem to be really necessary.

A variant of the first expl3 solution that pads the number with zeros to have the same length as the highest possible chosen number.

\documentclass{article}
\usepackage{lcg}
\newcounter{randnumb}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\randomtabular}{ O{randnumb} m m m m }
% #1 = counter name (optional default randnumb)
% #2 = lowest value
% #3 = highest value
% #4 = rows
% #5 = columns
{
\int_set:Nn \l_dierckx_padto_int { \tl_count:n { #3 } }
\chgrand[first=#2, last=#3, counter=#1]
\dierckx_random_tabular:nnn {#1}{#4}{#5}
}
\tl_new:N \l_dierckx_tabular_tl
\tl_new:N \l_dierckx_temp_tl

{
\tl_set:Nx \l_dierckx_temp_tl { \arabic{#1} }
\tl_set:Nx \l_dierckx_temp_tl
{
\prg_replicate:nn { \l_dierckx_padto_int - \tl_count:N \l_dierckx_temp_tl } { 0 }
\l_dierckx_temp_tl
}
\tl_put_right:Nx \l_dierckx_tabular_tl { \l_dierckx_temp_tl #2 }
}

\cs_new_protected:Npn \dierckx_random_tabular:nnn #1 #2 #3
{
\tl_clear:N \l_dierckx_tabular_tl
\prg_replicate:nn { #2 }
{
\prg_replicate:nn { #3 - 1 }
{
\rand
\__dierckx_padnumber:nn { #1 } { & }
}
\rand
\__dierckx_padnumber:nn { #1 } { }
\tl_put_right:Nn \l_dierckx_tabular_tl { \\ }
}
\begin{tabular}{*{#3}{r}}
\l_dierckx_tabular_tl
\end{tabular}
}
\ExplSyntaxOff

\begin{document}

\randomtabular{0}{100000}{6}{4}

\end{document}


• I do accept 4444...4 to be a possible random sequence... but... with a 2^31 space for seed the odds to get this sequence with a random seed are about 0.3E-8. And i tried different seeds... besides, as \rand\rand changed the complete table, one can be pretty sure something was wrong. But I'm glad someone pointed me on what exactly was wrong... – long tom Oct 25 '12 at 8:34
• i dropped the second part of code in a .sty file. so i'm able to reuse them from now on. – long tom Oct 25 '12 at 9:18
• If you choose the max number as, say 100 000, how can you get the random numbers to print zeros for numbers like 00257 and 03498? – azetina Apr 20 '15 at 19:40
• @azetina There should be a question about padding a number with zeros. – egreg Apr 20 '15 at 19:41
• @egreg Let me search and see what I can find about padding with zeros. I was about to ask about how to create a random number table for a statistics class I am teaching and I stumbled upon your answer. Am amazed as to how you achieved it. I am still a little puzzled as to some parts of the expl3 coding but I will look into it before I make further comments. Thanks :) – azetina Apr 20 '15 at 19:44

I made a quick tikz solution. You may use \pgfmathsetseed{} for repeatable results.

\documentclass{article}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,5}{
\foreach \y in {1,...,5}{
\pgfmathrandominteger{\a}{0}{4}
\node at (\x/2,\y/2){\a};
}
}
\end{tikzpicture}

\end{document}


result:

Here is a short example. The \tal command generates a random number. The \sekscifret command uses \tal and generates and writes a number with 6 digits. The loop inside the table inserts such numbers in columns and rows.

\documentclass{article}

\usepackage[english]{babel}
\usepackage{lcg}
\usepackage{forloop}

\newcounter{ct}
\newcounter{ctA}
\newcommand{\tal}{\chgrand[first=0,last=9,counter=randTal]\rand\arabic{randTal}}
\newcommand{\sekscifret}{\forloop{ct}{1}{\value{ct} < 7}{\tal}}

\begin{document}

\begin{tabular}{r r r r}

\forloop{ctA}{1}{\value{ctA} < 7}{

\sekscifret&\sekscifret&\sekscifret&\sekscifret
\\}

\end{tabular}

\end{document}