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 ?
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}
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.
\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}
1
for all \MakeTerm
s. 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
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}
Here is a version that is adapted from Generating a worksheet [1]. 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) [2] (Many thanks to Qrrbrbirlbel for helping to locate my previous answers).
\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
.+ -
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).\documentclass{article}
\usepackage{mathtools}
\usepackage{xstring}
\usepackage{enumitem}
\usepackage{tikz}
\usepackage{tkz-fct}
% https://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}}%
}%
% https://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}
[1] https://tex.stackexchange.com/questions/42173/generating-a-worksheet/tkx-fct
is only need to be able to provided reduced fractions. - Peter Grill
Here's a solution using PythonTeX [1]. 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}
Currently, the Python code can't be in the preamble, but that will be fixed in the next release, which should be out soon.
[1] https://github.com/gpoore/pythontexHere'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}
+
or-
I would justrandominteger
between-6
and6
, for example. (If0
is not allowed put it in a loop that is exited when the result is not0
.) - Qrrbrbirlbel