# Is there any better way to generate random unique quadratic equations with rational zeros, simplest integer coefficients?

This is my attempt but I want to make it more compact if possible.

Expand[(Numerator[#[[1]]] x +
Denominator[#[[1]]]) (Numerator[#[[2]]] x +
Denominator[#[[2]]])] == 0 & /@ (Rationalize[#, 0] & /@
RandomReal[{-1, 1}, {10, 2}, WorkingPrecision -> 2]) //
TableForm // TeXForm


# Edit 1

Requirements:

1. Rational roots.
2. Integer coefficients.
3. Simplest forms. For example, 9x^2+18x+81=0 must be simplified as 3x^2+2x+9=0.
4. No duplication. For example, 3x^2+2x+9=0 occurs at the i-th row so it must not occurs again at any other rows.
5. No linear equations. For example, 2x-5=0 must be removed from the list.

# Edit 2

Clear[list, n];
n = 10;
list = {};
For[i = 1, i <= 4 n, i++,
rnd = RandomInteger[{-10, 10}];
If[Mod[i, 2] == 1, While[rnd == 0, rnd = RandomInteger[{-10, 10}]]];
list = Append[list, rnd]];
list = Partition[list, 4];
Expand[(#1 x + #2) (#3 x + 4)] == 0 & @@@ list // TableForm // TeXForm


is my attempt but the result still does not conform to the third and fourth constraints.

• Do you want your polynomials to have integer coefficients? It looks like it from your code, but you don't explicitly say so. Jul 27 '18 at 18:47
• Let me accept the best answer in 24 hours from now so you can edit your answer as much as you can and add other new answers. Thank you! Jul 28 '18 at 7:11

### First attempt:

You could always use RandomInteger instead of RandomReal:

n = 10;
Expand[(#1 x + #2) (#3 x + #4)] == 0 & @@@ RandomInteger[{-20, 20}, {n, 4}] // TableForm // TeXForm


### After edits:

The new modifications make things a bit trickier. The following code is still relatively compact and satisfies all but condition #4:

n = 10;
FactorTermsList[(#1 x + #2) (#3 x + #4)][[2]] == 0 &
@@@ RandomChoice[ Join[Range[1, 20], -Range[1, 20]], {n, 4}]
// TableForm // TeXForm


The use of RandomChoice on the set given means that none of the inputs will ever be zero. We will therefore have no linear polynomials in the list. We will also have no polynomials with a root of $x = 0$; this is not specifically allowed or prohibited in the criteria. The function FactorTermsList splits any polynomial into an overall factor and a polynomial with (I believe) integer coefficients, returning a list whose second element is the reduced polynomial.

This code will occasionally produce a duplicate. If it is not necessary to produce a given number of polynomials every time, the best fix for this is simply to feed the result through DeleteDuplicates before applying TableForm and TexForm. If one requires a given number of polynomials every time, however, it may be necessary to employ some kind of iterative procedure, as in LouisB's answer. Such code will probably not be as compact.

### Code with no duplicates:

Here's what I came up with:

n = 10;
list = DeleteDuplicates[Flatten[Table[i/j, {i, -30, 30}, {j, 1, 30}]]];
FactorTermsList[(x - #1) (x - #2)][[2]] == 0 & @@@ ArrayReshape[RandomSample[list, 2 n], {n, 2}] // TableForm // TeXForm


Here, list contains all rational numbers which, when reduced to lowest terms $\pm p/q$, have $|p|, |q| \leq 30$; the use of DeleteDuplicates guarantees that all entries in list are unique. The use of RandomSample then generates a set of roots for the polynomials; since list has no duplicates, all of the polynomials so generated will be unique.

samplesize = 10;
bounds = 10^6;
polys = Expand[Times @@ MinimalPolynomial[Rational @@@ #, x]] & /@
RandomInteger[{- bounds, bounds}, {samplesize, 2, 2}];

GCD @@@ (CoefficientList[#, x] & /@ polys)


{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}

eqns = Thread[Equal[polys, 0]];
eqns // Column // TeXForm


$\begin{array}{l} 140651731 x^2-947453401 x+1192155174=0 \\ 42619409955 x^2-156834640182 x+105944698439=0 \\ 171031814512 x^2-180603256345 x-36494306637=0 \\ 406325216376 x^2-733794982355 x+158400960325=0 \\ 384027072051 x^2-67574138411 x-3482014962=0 \\ 2722871685 x^2-454772677 x-2323633312=0 \\ 587464071759 x^2-206481068351 x-222421556780=0 \\ 4259409456 x^2+25984801201 x+25077646390=0 \\ 1234752125 x^2+2712470855 x+1446568046=0 \\ 43373751289 x^2-245250942690 x-381393296091=0 \\ \end{array}$

• need to add some modifications to avoid zero denominator...
– kglr
Jul 28 '18 at 6:11

If the two rational roots, $p$ and $q$, have a common denominator $r$, then $r$, $s=rp$ and $t=rq$ are integers. The quadratic equation can be written $$(x-p)(x-q)=0 \,\text{,}$$ or $$r^2 x^2 -r(s+t)x + s t = 0 \,.$$ So, we can pick any three integers $r$, $s$ and $t$ in a convenient range. Provided that $r\neq 0$, we can form a quadratic equation with integer coefficients and rational roots $p = s/r$ and $q = t/r$.

ClearAll["Global*"]
quadratic = r^2 x^2 - r (s + t) x + s t
roots = Solve[quadratic == 0, x]


We can generate the quadratic with

Expand[(#1^2 x^2 + (#2 + #3) x + #2 #3) == 0 & @@@
RandomInteger[{-10, 10}, {10, 3}]] // TableForm // TeXForm


Edit 1

Recognizing that the above does not satisfy the latest requirements, we adopt the form proposed by Michael Seifert. The following code should satisfy the latest requirements, but it is not particularly compact:

nEqns = 10;
coeffs = {};
While[Length[coeffs] < nEqns,
candidate = {#1 #3, #2 #3 + #1 #4, #2 #4} & @@
RandomInteger[{-10, 10}, 4];
acceptable = (Not[MemberQ[coeffs, #]] &&
First[#] > 1 &&
GCD @@ # == 1) &@ candidate;
If[acceptable, AppendTo[coeffs, candidate]];
]

({x^2, x, 1} . # == 0) & /@ coeffs // TableForm // TeXForm


The above takes 4 random integers and forms the 3 coefficients of $a x^2+bx+c$. If candidate $(a,b,c)$ is already on the list of coefficients, it is rejected. Otherwise, $a$ must be positive and the GCD of $(a,b,c)$ must be 1. Note the use of Dot[] in the last line.

To check that the solutions are rational, we could do this:

Solve[#, x] & /@ (({x^2, x, 1} . # == 0) & /@ coeffs) // Column
`
• Any linear equations must be excluded from the list. Jul 27 '18 at 22:19