Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
9  
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
show 1 more comment

2 Answers

up vote 8 down vote accepted

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}

enter image description here

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}

enter image description here


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.

share|improve this answer
    
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
add comment

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:

screenshot

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.