pgfmath and doing some simple calculations using a variable

I'm creating addition worksheets for little oompa loompas. It works using:

\documentclass{article}

\usepackage{geometry}
\geometry{letterpaper, portrait, margin=1.5cm, tmargin=2.5cm }
\usepackage{tabularx}
\usepackage{array}
\usepackage{siunitx}
\usepackage{tikz}
\usepackage{pgf}
\DeclareMathSizes{10.0}{17}{12}{12}

\begin{document}
\begin{flushleft}

% fixed width, right justified column
\newcolumntype{R}[1]{>{\raggedleft\arraybackslash}p{#1}}

% print 2 numbers
%
%     42
%    + 7
%
\newcommand{\allan}{
& \pgfmathparse{random(10,99)}\pgfmathresult \\
+ & \pgfmathparse{random(0,9)}\pgfmathresult \\
}

% create 7x9 grid of addition problems
\foreach \n in {0,...,8}{
\foreach \n in {0,...,6}{
\begin{tabularx}{1.8cm}{>{$}R{.3cm}<{$} >{$}R{.7cm}<{$}}
\allan
\hline
\end{tabularx}
\hspace{.4cm}
}
\vspace{1.5cm}
}

\end{flushleft}
\end{document}


However, in the \newcommand \allan, what I'd really like is to be able to eliminate addition problems that have a carry in them.

something like:

random1 = first random # from 10 to 99

random2 = 2nd random # from 0 to (9 - (random1 modulo 10))

1 Answer

The result of the calculation can be directly assigned to a macro using \pgfmathsetmacro.

Table cells are local groups, therefore the following definition of \allan first performs the calculations, defines a macro for the table rows with the expanded calculation results and calls the macro to actually set the rows:

\newcommand{\allan}{
\pgfmathsetmacro\RandomA{random(10,99)}%
\pgfmathsetmacro\RandomB{random(0, int(9 - mod(\RandomA,10)))}%
\edef\next{%
& \RandomA \noexpand\\%
+ & \RandomB \noexpand\\%
}%
\next
}


Full example:

\documentclass{article}

\usepackage{geometry}
\geometry{letterpaper, portrait, margin=1.5cm, tmargin=2.5cm }
\usepackage{tabularx}
\usepackage{array}
\usepackage{siunitx}
\usepackage{tikz}
\usepackage{pgf}
\DeclareMathSizes{10.0}{17}{12}{12}

\begin{document}
\begin{flushleft}

% fixed width, right justified column
\newcolumntype{R}[1]{>{\raggedleft\arraybackslash}p{#1}}

% print 2 numbers
%
%     42
%    + 7
%
\newcommand{\allan}{
\pgfmathsetmacro\RandomA{random(10,99)}%
\pgfmathsetmacro\RandomB{random(0, int(9 - mod(\RandomA,10)))}%
\edef\next{%
& \RandomA \noexpand\\%
+ & \RandomB \noexpand\\%
}%
\next
}

% create 7x9 grid of addition problems
\foreach \n in {0,...,8}{
\foreach \n in {0,...,6}{
\begin{tabularx}{1.8cm}{>{$}R{.3cm}<{$} >{$}R{.7cm}<{$}}
\allan
\hline
\end{tabularx}
\hfill
}
\par
\vspace{1.5cm}
}

\end{flushleft}
\end{document}


Variant without tabularx, which fills the space on the page:

\documentclass{article}

\usepackage{geometry}
\geometry{letterpaper, portrait, margin=1.5cm, tmargin=2.5cm }
\usepackage{tabularx}
\usepackage{array}
\usepackage{siunitx}
\usepackage{tikz}
\usepackage{pgf}
\DeclareMathSizes{10.0}{17}{12}{12}

\begin{document}
\begin{flushleft}
\setlength{\parskip}{0pt plus 1fill}
\setlength{\parfillskip}{0pt}
\setlength{\tabcolsep}{2\tabcolsep}% make the lines a little longer

% print 2 numbers
%
%     42
%    + 7
%
\newcommand{\allan}{
\pgfmathsetmacro\RandomA{random(10,99)}%
\pgfmathsetmacro\RandomB{random(0, int(9 - mod(\RandomA,10)))}%
\edef\next{%
& \noexpand\leavevmode
\ifnum\RandomA<10 \noexpand\hphantom{0}\fi % if \RandomA can be smaller than ten
\RandomA \noexpand\\%
+ & \RandomB \noexpand\\%
}%
\next
}

% create 7x9 grid of addition problems
\foreach \n in {0,...,8}{
\foreach \n in {0,...,6}{
\begin{tabular}{>{$}l<{$} @{$\;$} >{$}r<{$}}
\allan
\hline
\vadjust{\vspace{1.1cm}}% place for result
\end{tabular}%
\hfill
}%
\par
}
\flushbottom
\newpage
\end{flushleft}
\end{document}


Hint: \pgfmathsetseed{<number>} can be used to get reproducible results.

• thanks. I had spent a couple of hours going down various rabbit holes trying to figure out how the heck one does a simple thing like this (well, simple in any of the other 25 languages I've dealt with). I knew LaTeX wasn't a programming language, but given it's flexibility, I felt sure it could do something like this, but even phrasing the question right for a search was hard. Aug 19, 2015 at 15:51
• One more thing. your 2nd modified code doesn't give me all the overfull hbox errors and pads things nicely to the right. However, on other sheets, if there is a difference between entries with 2 digits and 1 digit numbers, the columns will be jagged. that was why i was using tabularx. Any ideas? Aug 20, 2015 at 5:53
• (for example if it was 1-100 for the first digit and 1-9 for the second, the entries with 1-9 on the first digit will not line up with the ones with 10-99. ) Aug 20, 2015 at 6:01
• @allan See updated answer. Aug 20, 2015 at 6:46