Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to produce quadratic equation with integer coefficients. Here's my code using pgfmath.

\documentclass{article}
\usepackage{tikz}
\pgfmathsetseed{\pdfuniformdeviate 10000000} 
\begin{document}
$\pgfmathdeclarerandomlist{signe}{{+}{-}}%
\pgfmathrandomitem{\s}{signe}%
\pgfmathparse{random(2)}%
\pgfmathparse{ifthenelse(\pgfmathresult==1,"-"," ")}\pgfmathresult
\pgfmathrandominteger{\a}{1}{6}
\pgfmathparse{ifthenelse(\a==1," x^{2} ","\a x^{2}")}\pgfmathresult % coeff a
\pgfmathdeclarerandomlist{lincoeff}{{}{2}{3}{4}{5}{6}}
\pgfmathrandomitem{\b}{lincoeff}%
\pgfmathrandomitem{\s'}{signe}%
\pgfmathsetmacro{\e}{random(0,6)}
\pgfmathparse{ifthenelse(\e==0," ", " \s' \b x ")}\pgfmathresult % coeff b
\pgfmathrandominteger{\c}{0}{6}
\pgfmathrandomitem{\s''}{signe}%
\pgfmathparse{ifthenelse(\c==0,"","\s'' \c")}\pgfmathresult % coeff c
=0$
\end{document}

It works but it seems to be not a good way, I had some pain with the x-coeficient and my solution looks complicated. I tried to use an ifthenelse inside an other ifthenelse but without success. Is there a better way ?

share|improve this question
1  
Welcome to TeX.sx! Do you have a pseudo code within reach? Instead of randomizing over + or - I would just randominteger between -6 and 6, for example. (If 0 is not allowed put it in a loop that is exited when the result is not 0.) –  Qrrbrbirlbel Oct 30 '12 at 23:39
1  
Your question is similar to this one Maybe something useful in those answers as well? –  DJP Oct 31 '12 at 1:13
add comment

6 Answers

up vote 13 down vote accepted

Lots of if :)

\documentclass{article}
\usepackage{tikz}

\pgfmathsetseed{\pdfuniformdeviate 10000000} 

\newcommand{\rndcoeff}[1][1]{
\pgfmathrandominteger{\a}{\ifnum#1>1 1\else0\fi}{6}
\ifnum#1>1
    \pgfmathparse{rand>0?:"-"}\pgfmathresult\ifnum\a=1\else\a\fi x^2
\else
    \ifnum#1<1\relax
        \ifnum\a>0\relax
            \pgfmathparse{rand>0?"+":"-"}\pgfmathresult\a
        \fi
        \let\a\relax
    \else
    \ifnum\a>0\pgfmathparse{rand>0?"+":"-"}\pgfmathresult\ifnum\a=1\else\a\fi x\fi
    \fi
\fi
}
\newcommand{\givemesomequads}{
\rndcoeff[2]\rndcoeff\rndcoeff[0] = 0
}
\begin{document}
\foreach \x in {1,...,10}{
$\givemesomequads$ \par
}
\end{document}

enter image description here

share|improve this answer
add comment

Well, here is a solution that uses pgf only for the random integers.

Everything else is done with TeX's own conditionals and, in one instance, a loop.

Code

\documentclass{article}
\usepackage{pgf}

\pgfmathsetseed{\pdfuniformdeviate 10000000}

\newcommand*\MakeFirstTerm[2]{
    \loop\pgfmathrandominteger{\a}{#1}{#2}
        \ifnum\a<0\relax
            \let\iterate\relax
        \else\ifnum\a>0\relax
            \let\iterate\relax
        \fi
    \repeat
    \ifnum\a=1\relax\else
        \a
    \fi
}

\newcommand*\MakeTerm[3][]{
    \pgfmathrandominteger{\a}{#2}{#3}
    \ifnum\a=0\relax\else
        \ifnum\a<0\relax\else+\fi
        \a#1
    \fi
}
\newcommand*{\quadeq}{
    \MakeFirstTerm{-6}{6}x^2 \MakeTerm[x]{-6}{6} \MakeTerm{-6}{6} = 0
}
\begin{document}
$\quadeq$ \par $\quadeq$ \par $\quadeq$ \par $\quadeq$ \par $\quadeq$
\end{document}

Output

enter image description here

share|improve this answer
    
@Percusse \lbreak –  Roland Oct 31 '12 at 11:10
    
@Percusse Not easy for me to comment :-) I have learnt with your two codes. It seems necessary to use a TeX-primitive like \ifnum or \loop. I thought it was possible only with pgfmath commands. –  Roland Oct 31 '12 at 11:15
    
@Roland I just noticed that my solution gives leading 1 for all \MakeTerms. This is probably not allowed in front of x`. I can later post a correction … but I'm sure with all the answers here you can easily whip something up. –  Qrrbrbirlbel Oct 31 '12 at 11:29
    
I didn't see that first time, so I just add some lines in my answer, which is yours in fact. May be it is not the more compact way but it's simple. –  Roland Oct 31 '12 at 20:41
add comment

Here's a pair of lualatex solutions. Both provide \genrand which takes an optional integer argument that specifies the maximum (absolute) value of the coefficients, the default is 10. The first uses pattern matching and the second is a somewhat odd variation of the standard approach.

Pattern Matching:

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
local rand = math.random
function makequad(n)
    n = n or 10
    local a,b,c = rand(-n,n),rand(-n,n),rand(-n,n)
    while a==0 do a = rand(-n,n) end
    local s = a.."x^2".."+"..b.."x".."+"..c
    s = string.gsub(s,"%+%-","-") 
    s = string.gsub(s,"[%D]0[^%d]?","")
    s = string.gsub(s,"([+-])1x","%1x")
    s = string.gsub(s,"^([%D]?)1x","%1x")
    tex.sprint(s.."=0")
end
\end{luacode*}

\newcommand\genquad[1][]{\directlua{makequad(#1)}}

\begin{document}
$\genquad$\par
$\genquad[20]$
\end{document} 

Odd variation of standard approach (I was trying to be clever):

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
local rand = math.random

local function zapone(n)
    if math.abs(n)==1 then
        n = ""
    end -- if
    return n
end -- function

local function gensign(x)
    local n = rand(1,2)
    if n > 1 then 
        return "-"
    elseif x == nil then 
        return ""
    end -- if
    return "+"
end -- function

function makequad(n)
    n = n or 10
    local a,b,c = rand(1,n),rand(0,n),rand(1,n)
    if b==0 then
        tex.print(gensign()..zapone(a).."x^2"..gensign(1)..c.."=0")
    else
        tex.print(gensign()..zapone(a).."x^2"..gensign(1)..zapone(b).."x"..gensign(1)..c.."=0")
    end -- if
end -- function
\end{luacode*}

\newcommand\genquad[1][]{\directlua{makequad(#1)}}

\begin{document}
$\genquad$\par
$\genquad[20]$
\end{document} 

enter image description here

share|improve this answer
    
Your code tells me : learn lua ! :-) I need to do this, it will be easier than learn TeX ... –  Roland Oct 31 '12 at 11:18
add comment

Here is a version that is adapted from Generating a worksheet. I have enhanced this earlier solution by including an automatic conversion to a reduced faction for the case of equal roots using the techniques outlined in Automatically add fractions and reduce the result (if neccessary) (Many thanks to Qrrbrbirlbel for helping to locate my previous answers).

Notes:

  • I define \newcommand*{\Difficulty}{10}. This number is used to determine the range of the random numbers that are generated. In this case with it set to 10, the random numbers will be real numbers in the range 1...10.

Further Improvements:

  • Complete macros to generate only quadratic equations with distinct real and imaginary roots.
  • Generate negative numbers as well. In this case it would be advisable to include some logic so that we do not end up with + - as in the linked to example in the question. One way would be just to generate another random number from 0..1 and use a - sign instead of a + sign (or no sign as in the leading numbers) if the random number generated was greater than 0.6 (assuming you wanted approximately 40% of the questions to have negative signs, which also controls the level of difficulty dependent on the grade level).

enter image description here

Code:

\documentclass{article}
\usepackage{mathtools}
\usepackage{xstring}
\usepackage{enumitem}
\usepackage{tikz}

\usepackage{tkz-fct}

% http://tex.stackexchange.com/questions/28628/automatically-add-fractions-and-reduce-the-result-if-neccessary/
\newcommand*{\fracReducedTkz}[2]{\tkzReducFrac{#1}{#2}\frac{\tkzMathFirstResult}{\tkzMathSecondResult}}%


\newcommand*{\SuppresIfLeadingOne}[1]{%
    \IfEq{#1}{1}{}{\pgfmathprintnumber[int detect]{#1}}%
}%

% http://tex.stackexchange.com/questions/42173/generating-a-worksheet/
\newcommand*{\Difficulty}{10}%

\newcommand{\QuadraticEquations}[1]{%
    \foreach \i in {1,...,#1}{%
      \pgfmathtruncatemacro{\A}{random(\Difficulty)}%
      \pgfmathtruncatemacro{\B}{random(\Difficulty)}%
      \pgfmathtruncatemacro{\C}{random(\Difficulty)}%
      \item   $\SuppresIfLeadingOne{\A} x^2 + 
              \SuppresIfLeadingOne{\B} x + 
              \pgfmathprintnumber[int detect]{\C}% Don't suppress this if it is a one
              = 0$% 
    }%
}%

\newcommand{\QuadraticEquationsEqualRoots}[1]{%
    \foreach \i in {1,...,#1}{%
      \pgfmathtruncatemacro{\A}{random(\Difficulty)}%
      \pgfmathtruncatemacro{\B}{random(\Difficulty)}%
      \pgfmathtruncatemacro{\numerator}{\B*\B}
      \pgfmathtruncatemacro{\denominator}{4*\A}
      \item   $\SuppresIfLeadingOne{\A} x^2 + 
              \SuppresIfLeadingOne{\B} x + 
              \fracReducedTkz{\numerator}{\denominator}% Don't suppress this if it is a one
              = 0$%  
    }%
}%



\begin{document}
\section{Random Quadratic Equations:}
\begin{enumerate}
  \QuadraticEquations{4}
\end{enumerate}
%
\section{Random Quadratic Equations (Equal Roots):}
\begin{enumerate}
  \QuadraticEquationsEqualRoots{4}
\end{enumerate}
\end{document}
share|improve this answer
    
I save that to study later, there are a lot of commands I don't know and neither tkz-fct, although I use tkz-tab a lot. –  Roland Oct 31 '12 at 11:23
    
@Roland: tkx-fct is only need to be able to provided reduced fractions. –  Peter Grill Oct 31 '12 at 16:57
    
thank you for this detail. –  Roland Nov 1 '12 at 2:11
add comment

Here's a solution using PythonTeX. If all you need is just random quadratics, then the lualatex and pgf solutions are probably better. But if you will ultimately be working with the equations, then access to Python's SymPy library for symbolic math may be useful. One advantage of this approach is that the code is very compact, since SymPy does all the work for us.

\documentclass{article} 

\usepackage{pythontex}

\begin{document}

\begin{sympycode}
from sympy.stats import DiscreteUniform, sample
x = Symbol('x')
a = DiscreteUniform('a', range(-10, 11))
b = DiscreteUniform('b', range(-10, 11))
c = DiscreteUniform('c', range(-10, 11))
def randquad():
    return Eq(sample(a)*x**2 + sample(b)*x + sample(c))
\end{sympycode}

\newcommand\randquad{\sympy{randquad()}}


\[ \randquad \]

\[ \randquad \]

\[ \randquad \]


\end{document}

sample equations

Currently, the Python code can't be in the preamble, but that will be fixed in the next release, which should be out soon.

share|improve this answer
    
It looks very compact indeed ! However I dont'have the pythontex package in TeXLive 2012 so I could not try your answer. There is a another problem, more important :-), I don't know Python et I am not a programmer at all, so if I can learn some simple features of TeX (like \ifnum) et a bit of luatex it will be already a lot ! –  Roland Oct 31 '12 at 20:37
add comment

Here's Qrrbrbirlbel answer with some more if to avoid the 1 before x.

\documentclass{article}
\usepackage{pgf}

\pgfmathsetseed{\pdfuniformdeviate 10000000}

\newcommand*\MakeFirstTerm[2]{
\loop\pgfmathrandominteger{\a}{#1}{#2}
    \ifnum\a<0\relax
        \let\iterate\relax
    \else\ifnum\a>0\relax
        \let\iterate\relax
    \fi
\repeat
\ifnum\a=1\relax\else
\ifnum \a=-1 -\relax \else
   \a
  \fi
\fi
}

\newcommand*{\MakeSecondTerm}[2]{
\pgfmathrandominteger{\a}{#1}{#2}
\ifnum \a=0\relax \else
\ifnum \a>1 + \a x \relax \else
  \ifnum \a=1 +x\relax \else
     \ifnum \a=-1 -x\relax \else
         \a x \relax
     \fi
   \fi
 \fi
\fi
}

\newcommand*{\MakeThirdTerm}[2]{
\pgfmathrandominteger{\a}{#1}{#2}
\ifnum \a=0\relax \else
  \ifnum \a<0 \a\relax \else
    +\a\relax
  \fi
\fi
}

\newcommand*{\quadeq}{
\MakeFirstTerm{-6}{6}x^2 \MakeSecondTerm{-6}{6} \MakeThirdTerm{-6}{6} = 0
}
\begin{document}
$\quadeq$ \par $\quadeq$ \par $\quadeq$ \par $\quadeq$ \par $\quadeq$
\end{document}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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