Setting up a quadratic-equation factoring worksheet: How to get rid of unwanted zeroes & ones?

To pick random distinct numbers \b and \d with \d in the range 1..10 and \d in the range -10,...,-1 I would use

 \pgfmathsetmacro{\d}{int(random(1,10)}
 \pgfmathsetmacro{\b}{int(random(1,9))}

now replace \b with -\b if \b<\d and with -1-\b otherwise.

With your printing issue with the coefficients you just need another \ifnum branch. In fact, you need two because rather than printing -1x you want to print -x.

Here's your MWE with these modifications:

\documentclass{article}

\usepackage[margin=1.2cm]{geometry}
\usepackage{ifthen}
\usepackage{multicol}
    \setlength{\columnsep}{1.5cm}
\usepackage{pgf}
\usepackage{pgffor}

\setlength{\parindent}{0pt}

\pagestyle{empty}

\pgfmathsetseed{\number\pdfrandomseed}


% How to make sure that we don't get a difference of squares, i.e. if \b=-\c, then the middle term will be zero and it's a DOS.
\newcommand{\InitVariables}
{%
 \pgfmathsetmacro{\d}{int(random(1,10)}
 \pgfmathsetmacro{\b}{int(random(1,9))}
 \ifnum\b<\d\pgfmathsetmacro{\b}{int(-\b)}%
 \else\pgfmathsetmacro{\b}{int(-1-\b)}%
 \fi
 \pgfmathsetmacro{\B}{int(\d+\b)}
 \pgfmathsetmacro{\C}{int(\b*\d)}
}

\newcommand{\trinomial}
{%
\InitVariables
\((x\b)(x+\d)=x^2 \ifnum\B<0\ifnum\B=-1-\else\B\fi\else+\ifnum\B>1\B\fi\fi x\C\)
}

\newcommand{\ManyTrinomials}[1]
{%
\foreach \x in {1,2,3,...,#1}
{\trinomial \\}
}

\begin{document}

\ManyTrinomials{50}

\end{document}

together with a random snapshot of the output:

enter image description here

Depending on what else you are doing it might be better to write a general macro for pretty printing polynomials.

EDIT

Here is a version with a \printpolynomial macro for "pretty printing polynomials". The macro takes comma separated list of coefficients, so

\printpolynomial{3,-2,1}% --> 3x^2-2x+1

Note that the macro assumes that it is in mathematics mode, so the above really ought to be $\printpolynomial{3,-2,1}$.

To do this the code first has a dry run through the coefficients to degree the maximum degree of the polynomial, called \polydeg -- actually, this is the degree plus one. It then goes through the coefficients again and prints them. A macro \plusseperator is sued to cope withe the annoying case when many of the leading coefficients are 0:

\printpolynomial{0,0,0,0,0,2,-2}%. -> 2x-2

In the extreme case, \printpolynomial{0,0,0,0,0} prints 0. IN addition to worrying about the coefficients being 1 and --1 there are additional complications with the exponents and in dealing with polynomials like \printpolynomial{1,1}, where the coefficient of the constant term does need to printed.

As a final bonus, the macro accepts an optional argument, which is the name of the determinant. So

\printpolynomial[y]{3,-4,2,1}%. --> 3y^3-4y^2+2y+1

The macro can be shortened a little if you print the polynomials with increasing exponents; that is, in the form a_0+a_1x+a_2x^2+...+a_nx^n.

Here is the revised code:

\documentclass{article}

\usepackage[margin=1.2cm]{geometry}
\usepackage{ifthen}
\usepackage{multicol}
    \setlength{\columnsep}{1.5cm}
\usepackage{pgf}
\usepackage{pgffor}

\setlength{\parindent}{0pt}

\pagestyle{empty}

\pgfmathsetseed{\number\pdfrandomseed}

% usage: \printpolnomial[name of indeterminate]{a_n, ... , a_1, a_0}
\newcommand\printpolynomial[2][x]{%
  % need to loop over #2 once to find the degree (actually, polydeg=degree+1)
  \foreach \coeff [count=\polydeg, remember=\polydeg] in {#2} {}
  \let\plusseperator\relax%  as the leading coefficients may be zero use this instead of +
  \foreach \coeff [count=\term, evaluate=\term as \pdeg using int(\polydeg-\term)] in {#2} {%
     \ifnum\coeff=0\relax% do nothing
     \else
       \ifnum\coeff>0\relax%
          \plusseperator% print a + if some terms have already appeared
          \ifnum\coeff=1\relax%
            \ifnum\pdeg=0\relax1\fi% print 1 if constant term
          \else\coeff% print coefficient if it is greater than 1
          \fi%
       \else\ifnum\coeff<0%
          \ifnum\coeff=-1\relax%
             \ifnum\pdeg=0\relax-1\else-\fi% print -1 if constant term
           \else\coeff% print \coeff
           \fi%
         \fi%
       \fi%
       \ifnum\pdeg=0\relax%
       \else%
         \ifnum\pdeg=1\relax #1\else {#1}^{\pdeg}\fi% print the power of #1 = x
       \fi%
       \gdef\plusseperator{+}% change \plusseperator to + as polynomial is non-zero
     \fi%
   }%
   \ifx\plusseperator\relax 0\fi% zero polynomial
}


% How to make sure that we don't get a difference of squares, i.e.
% if \b=-\d, then the middle term will be zero and it's a DOS.
\newcommand{\InitVariables}
{%
 \pgfmathsetmacro{\d}{int(random(1,10)}
 \pgfmathsetmacro{\b}{int(random(1,9))}
 \ifnum\b<\d\pgfmathsetmacro{\b}{int(-\b)}%
 \else\pgfmathsetmacro{\b}{int(-1-\b)}%
 \fi
 \pgfmathsetmacro{\B}{int(\d+\b)}
 \pgfmathsetmacro{\C}{int(\b*\d)}
}

\newcommand{\trinomial}
{%
\InitVariables
$(\printpolynomial{1,\b})(\printpolynomial{1,\d})
    = \printpolynomial{1,\B,\C}$
}

\newcommand{\ManyTrinomials}[1]
{%
\foreach \x in {1,2,3,...,#1}
    {\trinomial\\}
}

\begin{document}

$\printpolynomial{2,1,3,-2,0}$

$\printpolynomial{0,1,3,-2,0}$

$\printpolynomial{0,0,0,0,0}$

\ManyTrinomials{50}

\end{document}

You can make coding a lot easier on yourself if you're willing to use the sagetex package documented here. In addition to the computing power of a computer algebra system you get the benefit of easy to program Python commands and even built in commands to make the output pretty through the latex() command. The line of code below containing latex(factor(poly)) tells Sage to factor the polynomial that was created and express the result in LaTeX code.

\documentclass{article}%
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
x = var('x')
Problems = r"Factor each quadratic:\\ \begin{enumerate}"
for i in range(0,20):
    r1 = Integer(randint(-10,10))
    r2 = Integer(randint(-10,10))
    while r1 == -r2:
        r2 = Integer(randint(-10,10))
    poly = expand((x-r1)*(x-r2))
    Problems += r"\item $%s = %s$"%(latex(poly),latex(factor(poly)))
Problems += r"\end{enumerate}"
\end{sagesilent}
\sagestr{Problems}
\end{document}

The output is shown running in SagemathCloud: enter image description here

And getting used to Sage and the sagemath package pays off in making all sorts of math worksheets easier--Sage handles all levels of math. You do need Sage installed locally on your computer OR a free SagemathCloud account.


Just for good measure, here's a pure LuaLaTeX-based solution. Other than the luacode package, no further packages are required to generate the required output.

enter image description here

A full MWE:

% !TeX program = lualatex
\documentclass{article}
\usepackage{amsmath} % for 'align*' env.

%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function trinom ( n ) -- n: # of iterations (integer)
local f1,f2,g1,g2,s1
for i=1,n do -- Repeat the following code 'n' times

  -- f1 & f2: integers between -10 and 10, excl. 0
  repeat f1=math.random(-10,10) until f1~=0
  repeat f2=math.random(-10,10) until f2~=0 and f2~=-f1

  -- Compute additive and multiplicative factors 
  g1 = f1+f2 
  g2 = string.format("%+i", f1*f2) -- store as string

  -- Retrieve sign ("s1") of g1
  if g1<0 then s1 = "-" else s1 = "+" end
  g1 = tostring(math.abs(g1)) -- convert to abs. value
  -- Special treatment if abs(g1)=="1"
  if g1=="1" then g1 = "" end

  -- Generate output
  tex.sprint( "(x" .. string.format("%+i",f1) .. ")" ..
              "(x" .. string.format("%+i",f2) .. ")" ..
              "&= x^2" .. s1 .. g1 .. "x" .. g2 ) 
  -- Insert line-break directive if not (yet) at last line
  if n>1 and i<n then tex.sprint ( "\\\\" ) end 

end -- end of 'for' loop
end -- end of 'trinom' function
\end{luacode}

%% TeX-side code
\newcommand\ManyTrinomials[1]{\directlua{trinom(#1)}}

\begin{document}
\allowdisplaybreaks
\begin{align*}
\ManyTrinomials{30} % 30 rows
\end{align*}
\end{document}

Remark: If you don't want to embed the equations in an align* environment and, instead, simply want to print them out line by line, just change the chunk

     tex.sprint( "(x" .. string.format("%+i",f1) .. ")" ..
                 "(x" .. string.format("%+i",f2) .. ")" ..
                 "&= x^2" .. s1 .. g1 .. "x" .. g2 ) 

to

     tex.sprint( "(x" .. string.format("%+i",f1) .. ")" ..
                 "(x" .. string.format("%+i",f2) .. ")" ..
                 "= x^2" .. s1 .. g1 .. "x" .. g2 ) 

i.e., omit the & symbol.