Generating tables of random numbers

With the following definitions, you can define the parameters of your random numbers by

\setrand{<minimum>}{<maximum>}{<multiple of>}{<seed>}

A random number is generated by

\nextrand

which then can be accessed arbitrarily often using

\thisrand

Here is the code to be included in the preamble:

\usepackage{pgfmath}
\newcommand\randmin{}
\newcommand\randmax{}
\newcommand\randmultof{}
\newcommand\setrand[4]%
  {\def\randmin{#1}%
   \def\randmax{#2}%
   \def\randmultof{#3}%
   \pgfmathsetseed{#4}%
  }
\newcommand\nextrand
  {\pgfmathparse{int(int((rnd*(\randmax-\randmin+1)+\randmin)/\randmultof)*\randmultof)}%
   \xdef\thisrand{\pgfmathresult}%
  }

This definition will generate integers uniformly distributed between "minimum" and "maximum" which then are truncated to the next multiple of "multiple of". If you want to have the multiples themselves uniformly distributed, you have to choose a maximum that is smaller by one than a multiple. As an example, both of the settings

\setrand{0}{60}{5}{42}
\setrand{0}{64}{5}{42}

will generate uniformly distributed numbers between 0 and 60, the first one leading to uniform distribution before truncating to the next multiple, the second one to uniform distribution of the truncated numbers. Which of the two interpretations is the intended one isn't quite clear from the original post (at least not to me).

Here is a sample document illustrating the usage of these commands.

\documentclass{article}
\usepackage{pgfmath}
\newcommand\randmin{}
\newcommand\randmax{}
\newcommand\randmultof{}
\newcommand\setrand[4]%
  {\def\randmin{#1}%
   \def\randmax{#2}%
   \def\randmultof{#3}%
   \pgfmathsetseed{#4}%
  }
\newcommand\nextrand
  {\pgfmathparse{int(int((rnd*(\randmax-\randmin+1)+\randmin)/\randmultof)*\randmultof)}%
   \xdef\thisrand{\pgfmathresult}%
  }
\begin{document}
\setrand{0}{64}{5}{42} % random numbers between 0 and 60, multiples of 5, seed 42
\begin{tabular}[t]{ r r }
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand
\end{tabular}
\qquad
\setrand{0}{129}{10}{42} % random numbers between 0 and 120, multiples of 10, seed 42
\begin{tabular}[t]{ r r }
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand \\
\nextrand\thisrand & \thisrand
\end{tabular}

\end{document}

enter image description here


\documentclass[a4paper,11pt]{article}
\usepackage{tikz}
\begin{document}
\pgfmathsetseed{1}
\pgfmathparse{int(random(0,12)*5)}\let\vara=\pgfmathresult
\pgfmathparse{int(random(0,12)*5)}\let\varb=\pgfmathresult
\begin{tabular}[t]{ c c }
\vara & \vara \\  % keep var constant on row
\varb & \varb \\
\end{tabular}
\pgfmathparse{int(random(0,12)*10)}\let\varc=\pgfmathresult
\pgfmathparse{int(random(0,12)*10)}\let\vard=\pgfmathresult
\begin{tabular}[t]{ c c }
\varc & \varc \\  % keep var constant on row
\vard & \vard \\
\end{tabular}
\end{document}

TeX command names can not have numbers in them (with the default settings) so \vara not \var1


Works only with pdflatex and lualatex (because randint is not yet available with xelatex).

The \randomtable command accepts

  1. an optional arguments, the range r (default 20) meaning that multiples of 5 from 0 to 5‌r will be chosen (so the default is between 0 and 100);

  2. a mandatory argument, the number of rows.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\randomtable}{O{20}m}
 {
  \begin{tabular}{rr}
  \prg_replicate:nn { #2 } { \__norris_twice:f { \fp_eval:n { randint(0,#1)*5 } } \\ }
  \end{tabular}
 }

\cs_new:Nn \__norris_twice:n { #1 & #1 }
\cs_generate_variant:Nn \__norris_twice:n { f }
\ExplSyntaxOff

\begin{document}

\randomtable{2}\quad\randomtable{2}\quad\randomtable{4}

\bigskip

\randomtable[2]{2}\quad\randomtable[2]{2}\quad\randomtable[2]{4}

\end{document}

The second example shows that only 0, 5 and 10 can be selected.

enter image description here

If you want no repeated value, it's a bit more complicated (and of course slower):

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\randomtable}{O{20}m}
 {
  \seq_gclear:N \g__norris_generated_seq
  \begin{tabular}{rr}
  \prg_replicate:nn { #2 } { \__norris_generate:n { #1 } \\ }
  \end{tabular}
 }

\seq_new:N \g__norris_generated_seq
\tl_new:N \l__norris_random_number_tl
\cs_new:Nn \__norris_generate:n
 {
  \int_compare:nTF { #1 < \seq_count:N \g__norris_generated_seq }
   {
    \__norris_twice:n { ? }
   }
   {
    \tl_set:Nx \l__norris_random_number_tl { \fp_eval:n { randint(0,#1)*5 } }
    \seq_if_in:NVTF \g__norris_generated_seq \l__norris_random_number_tl
     {% redo
      \__norris_generate:n { #1 }
     }
     {
      \seq_gput_right:NV \g__norris_generated_seq \l__norris_random_number_tl
      \__norris_twice:V \l__norris_random_number_tl
     }
   }
 }

\cs_new:Nn \__norris_twice:n { #1 & #1 }
\cs_generate_variant:Nn \__norris_twice:n { V }
\ExplSyntaxOff

\begin{document}

\randomtable{2}\quad\randomtable{2}\quad\randomtable{4}

\bigskip

\randomtable[4]{2}\quad\randomtable[4]{2}\quad\randomtable[4]{5}\quad
\randomtable[4]{6}

\end{document}

In the last example, we have more rows than allowed by the range, so the last row has question marks.

enter image description here