6

I am trying to make some math fact equation sheets that are based on random number generation. I have quite a bit of learning to do... but this is where I think should start: Use random numbers to make LaTeX generate a string of equations for me.

Right now, the basic idea is that: I first have \pgfmathsetmacro{\A}{random(1,4)} set \A as 1,2, 3 or 4.

  1. If \A=1, then I want 1+2=3 to appear.
  2. If \A=2, then I want 2+1=3 to appear.
  3. If \A=3, then I want 3=2+1 to appear.
  4. If \A=4, then I want 3=1+2 to appear.

This is what I've got so far, but the nested \ifthen structure seems very inelegant and will basically not scale to when I have, say, 100 different equations to choose from instead of just 4.

What's a better way?

\documentclass{article}

\usepackage{pgf}
\usepackage{pgffor}
\usepackage{ifthen}

\pagestyle{empty}
\setlength{\parindent}{0pt}

% THE FOUR EQUATIONS
% 1.   1+2=3
% 2.   2+1=3
% 3.   3=2+1 
% 4.   3=1+2

\pgfmathsetseed{\number\pdfrandomseed}

\newcommand{\InitVariables}
{\pgfmathsetmacro{\A}{random(1,4)}} 

\newcommand*{\onefact}
{
 \InitVariables
 \ifthenelse
  {\equal{\A}{1}}{1+2=3}
   {
    \ifthenelse{\equal{\A}{2}}{3=2+1}
     {
      \ifthenelse{\equal{\A}{3}}{3=2+1}{3=1+2}
     }
   }
}

\newcommand{\myequations}[1]
{
 \foreach \x in {1,...,#1}
  {\onefact\\}
}

\begin{document}

\myequations{10} 

\end{document}
  • you are looking for cases – percusse Sep 19 '16 at 22:08
  • @percusse What are cases? – WeCanLearnAnything Sep 19 '16 at 22:14
7

If you have 100 different cases, then your code logic is wrong at some point. But for not too many cases you can do \ifcase

\documentclass{article}
\usepackage{pgfmath}

\pgfmathsetseed{\number\pdfrandomseed}
\pgfmathtruncatemacro{\A}{random(1,4)}

\begin{document}

\ifcase\A\relax%
  \or 1+2=3% Because \A starts from 1
  \or 2+1=3%
  \or 3=2+1%
  \or 3=1+2%
\fi

\end{document}
  • How does 100 cases imply something is wrong with the code logic? And what does \ifcase\A\relax mean? I can't make sense of it. – WeCanLearnAnything Sep 19 '16 at 22:26
  • @WeCanLearnAnything It means that you are doing a lookup so it shouldn't be a if or switch it should get the index and pick it up from some array/table/database whatever. It shouldn't list all the possibilities inline. – percusse Sep 19 '16 at 22:32
  • \ifcase works with integers. \A\relax means roughly after finishing \A stop looking for more numbers from this point and carry on with the code. – percusse Sep 19 '16 at 22:32
  • Hmm. How would I enter that array/table/database into LaTeX? Does that have to be a separate document or separate file?? – WeCanLearnAnything Sep 19 '16 at 22:37
  • search for datatools or pgfplotstable on this site – percusse Sep 19 '16 at 22:44
8

An ideal usecase for luatex:

\documentclass[margin=1mm, varwidth=true]{standalone}
\usepackage{luacode}

\begin{luacode}
  userdata = userdata or {}

  local questions = {
      "1 + 2 = 3" ,
      "2 + 1 = 3" ,
      "3 = 2 + 1" ,
      "3 = 1 + 2" ,
    }

  function userdata.fact()
    local A = math.random(#questions)
    tex.print(questions[A])
  end
\end{luacode}

\newcommand\Fact{\luadirect{userdata.fact()}}

\begin{document}

\begin{itemize}
  \item $\Fact$ 
  \item $\Fact$ 
  \item $\Fact$ 
  \item $\Fact$ 
  \item $\Fact$
\end{itemize}

\end{document}

which gives

enter image description here

6

I think it's easy to define essentially an array of options so you can define or redefine them as needed without having to define them all together in a nested structure.

\documentclass{article}

\usepackage{pgffor}

\usepackage{ifthen}

\pagestyle{empty}
\setlength{\parindent}{0pt}

% THE FOUR EQUATIONS
% 1.   1+2=3
% 2.   2+1=3
% 3.   3=2+1 
% 4.   3=1+2

\def\defchoice#1#2{\expandafter\def\csname X-#1\endcsname{#2}}
\defchoice{1}{$1+2=3$}
\defchoice{2}{$2+1=3$}
\defchoice{3}{$3=2+1$}
\defchoice{4}{$3=1+2$}

\pgfmathsetseed{\number\pdfrandomseed}

\newcommand{\InitVariables}
{\pgfmathsetmacro{\A}{random(1,4)}} 

\newcommand*{\onefact}
{%%%%%%%%%% dont forget % at end of line
 \InitVariables
  \csname X-\A\endcsname}


\newcommand{\myequations}[1]
{%
 \foreach \x in {1,...,#1}
  {\onefact\par}% don't end a paragraph with \\
}

\begin{document}

\myequations{10} 

\end{document}
  • This seems to look good. What does \def\defchoice#1#2{\expandafter\def\csname X-#1\endcsname{#2}} mean? I can't make sense of this... – WeCanLearnAnything Sep 19 '16 at 22:28
  • @WeCanLearnAnything: \def\defchoice#1#2{...} creates a macro called \defchoices{#1}{#2} where you have to supply it with [2] arguments (both are mandatory). It creates a macro called \X-#1 that contains the definition #2. However, creating a macro with numbers in its name is not easy. You have to do this using a \csname ... \endcsname construction, so we use \expandafter\def\csname ... \endcsname to first create the control sequence, then \define it. – Werner Sep 19 '16 at 22:41
  • Ok, I understand the \def\defchoice#1#2{...} part. But then there's another macro created within that? And why would it have the name \X- #1? – WeCanLearnAnything Sep 19 '16 at 23:56
  • @WeCanLearnAnything you need a macro name to store each choice, the prefix is arbitrary, I just chose \X-1, \X-2, \X-3 ... – David Carlisle Sep 20 '16 at 0:02
  • @WeCanLearnAnything tex.stackexchange.com/questions/39380/… – David Carlisle Sep 20 '16 at 0:04
5

LaTeX3 provides a fairly intuitive switch or case-like structure that allows you to define a case and its corresponding resolution. For your implementation, you can use:

\usepackage{xparse}    
\ExplSyntaxOn
\NewDocumentCommand{\onefact}{m}{
  \int_case:nnF {#1}
    {
      { 1 }{ 1 + 2 = 3 }
      { 2 }{ 2 + 1 = 3 }
      { 3 }{ 3 = 2 + 1 }
      { 4 }{ 3 = 1 + 2 }
    }
    { ? }
}
\ExplSyntaxOff

This will perform an integer comparison where the "else clause" (no match is found) results in ?. The use will be something like \onecase{2}, or \onecase{\A} where \A is defined as your random value between 1 and 4 (inclusive).

2

Scalable means “good interface”. We define a set of possible outcomes with

\defineset{<name>}{<a>,<b>,...}

and then \printfromset{<name>} will choose one of the outcomes at random; the random number will be computed from the number of possible outcomes associated with the particular set.

\documentclass{article}
\usepackage{xparse}

\input{random} % for random numbers
\randomi=\pdfrandomseed % initialize the seed

\ExplSyntaxOn

\cs_new_eq:NN \wcla_get_random:Nnn \setrannum
\int_new:N \l_wcla_random_int

\NewDocumentCommand{\defineset}{mm}
 {
  \tl_new:c { g_wcla_set_#1_tl }
  \int_zero:N \l_tmpa_int
  \clist_map_inline:nn { #2 }
   {
    \int_incr:N \l_tmpa_int
    \tl_gput_right:cx { g_wcla_set_#1_tl }
     {
      { \int_to_arabic:n { \l_tmpa_int } }
      { \exp_not:n { ##1 } }
     }
   }
 }

\NewDocumentCommand{\printfromset}{m}
 {
  \wcla_get_random:Nnn \l_wcla_random_int 
   { 1 }
   { \int_eval:n { \tl_count:c { g_wcla_set_#1_tl } /2 } }
  \int_case:nv { \l_wcla_random_int } { g_wcla_set_#1_tl }
 }
\cs_generate_variant:Nn \int_case:nn { nv }
\ExplSyntaxOff


\defineset{equations}{
  $1+2=3$,
  $2+1=3$,
  $3=2+1$,
  $3=1+2$
}
\defineset{letters}{A,B,C,D,E,F,G,H,I}

\begin{document}

\printfromset{equations}

\printfromset{equations}

\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}

\end{document}

The \defineset macro allocates a token list variable that's then filled in the format

{1}{<a>}{2}{<b>}...

which is good for \int_case:nn, provided we use the \int_case:nv variant. Note that the number of items is twice the number of outcomes.

The macro \printfromset generates a random number between 1 and half the length of the token list variable (we divide it by 2).

Here's a possible output

enter image description here

Note about random.tex, a set of macros by Donald Arsenau. The syntax is \setrannum<counter>{<low>}{<high>} which stores in the <counter> a random number between the integers <low> and <high> (extremes included). The seed is stored in the counter \randomi.

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.