I need to create an environment (let's call it randomizer) that randomly changes the order of its lines, which may contain any text or latex commands (assume without verifying that they don't break across lines).

For example, I have several tex files, each containing one problem and I want to generate a set of problems put in a random order. Then I would use


I want also to be able to control the random process, by having the possibility to specify a seed number for the generator.

  • 2
    You could take a look to examdesign: multiple versions of the same test can be generated automatically, with the ordering of questions within each section randomly permuted so as to minimize cheating; – knut Jan 11 '12 at 22:04
  • I already have the problems written in their specific format and using examdesign would mean to rewrite them. – digital-Ink Jan 11 '12 at 22:24
  • 2
    It's not only to use examdesign, but also to look, how they solved it there - perhaps you could use the same logic. – knut Jan 11 '12 at 23:06

Here is the solution based on the RANOMIZE-IN-PLACE procedure in the CLRS. The procedure is defined as

n = A.length
for i=1 to n
   swap A[i] with A[random(i,n)]

(CLRS does not like end for, so we do not use it either).

TeX code uses random.tex by Donald Arseneau (should be in your distribution). This code puts in 10 macros \csname num0\endcsname, \csname num1\endcsname, ... some random permutation of numbers 0..9 (I used macros instead of counters to save the latter). You can use this code to write something like \expandafter\input{file\csname num0\endcsname}, \expandafter\input{file\csname num1\endcsname} etc.


% Put 0..9 into \num0..\num9
\expandafter\edef\csname num\the\number\endcsname{\the\number}
\advance\number by 1

% Randomize
\setrannum{\randomnum}{\the\number}{9}  % Random number between \number and 9
\edef\tmpnum{\csname num\the\number\endcsname}
\expandafter\edef\csname num\the\number\endcsname{\csname
\expandafter\edef\csname num\the\randomnum\endcsname{\tmpnum}
\advance\number by 1

% Print the results:
Macro \textbackslash num\the\number\space contains \expandafter\csname
\advance\number by 1\relax\par
% To input in random order files file0.tex, file1.tex, file2.tex,... 
% use instead
% \number=0
% \loop\ifnum\the\number<10\relax
% \expandafter\input{file\csname num\the\number\endcsname}
% \advance\number by 1\relax
% \repeat


See random.tex documentation about seeding the generator.

Output example:

Macro \num0 contains 7
Macro \num1 contains 1
Macro \num2 contains 9
Macro \num3 contains 3
Macro \num4 contains 6
Macro \num5 contains 8
Macro \num6 contains 2
Macro \num7 contains 5
Macro \num8 contains 4
Macro \num9 contains 0
| improve this answer | |
  • How can this be applied when instead of sequential filenames I have some arbitrary filenames? – digital-Ink Jan 13 '12 at 15:05
  • You can put the filenames in an "array": \def\Input#1{\ifcase#1\input{first}\or\input{second}\or...\fi}. Thus the command \Input{0} inputs first.tex, etc. Then your last loop should call \expandafter\Input{\csname num\the\number\endcsname} – Boris Jan 13 '12 at 16:16
  • You can set the seed with \randomi42\relax % set Seed to 42. Else it is initialized in dependence on date and time. See sourcecode of random. – dexteritas Jul 14 '17 at 9:15

If you have luatex, you can also use lua. This uses the same shuffling method as Boris's answer, but in lua. Call lualatex with the following file:


\newcommand\SeedRnd[1][os.time()]{\directlua{rndseed = #1; math.randomseed(rndseed)}}

\SeedRnd %Takes an optional parameter if you want a specific random seed

local table = {#1}
function shuffle(t)
  local n = \#t
  while n > 1 do
    local k = math.random(n)
    t[n], t[k] = t[k], t[n]
    n = n - 1
  return t
for k,v in pairs(shuffle(table)) do tex.print("\string\\input{" .. v .. "}") end

Random seed: \RndSeed %so you will be able to recreate this order. 
\RndOrderLoad{'file1', 'file2', 'file3', 'file4'}

Note that the file names have to be written as lua strings, that is 'file1' or "file1", not just file1.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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