#include polynomial polynomial::operator * (polynomial p) const { set r_coeffs; for (set_const_iter i = coeffs; i; i ++) for (set_const_iter j = p.coeffs; j; j ++) r_coeffs.toggle (i.val () + j.val ()); return polynomial (r_coeffs); } pair, polynomial > polynomial::divide_with_remainder (polynomial d) const { assert (d != 0); polynomial r (COPY, *this); polynomial q; unsigned d_leading_exponent = d.coeffs.tail (); for (;;) { if (r == 0) break; unsigned r_leading_exponent = r.coeffs.tail (); if (r_leading_exponent < d_leading_exponent) break; for (set_const_iter i = d.coeffs; i; i ++) r.coeffs.toggle (r_leading_exponent - d_leading_exponent + i.val ()); q.coeffs.toggle (r_leading_exponent - d_leading_exponent); } assert (r == 0 || r.degree () < d.degree ()); // assert (*this == q*d + r); return pair, polynomial > (q, r); } polynomial polynomial::mod (polynomial d) const { assert (d != 0); polynomial r (COPY, *this); unsigned d_leading_exponent = d.coeffs.tail (); for (;;) { if (r == 0) break; unsigned r_leading_exponent = r.coeffs.tail (); if (r_leading_exponent < d_leading_exponent) break; for (set_const_iter i = d.coeffs; i; i ++) r.coeffs.toggle (r_leading_exponent - d_leading_exponent + i.val ()); } assert (r == 0 || r.degree () < d.degree ()); return r; } bool polynomial::divides (polynomial d) const { return mod (d) == 0; } polynomial polynomial::divide_exact (polynomial d) const { pair, polynomial > qr = divide_with_remainder (d); assert (qr.second == 0); return qr.first; } polynomial polynomial::gcd (polynomial b) const { // ??? can return *this polynomial a = *this; while (b != 0) { pair, polynomial > a_qr = a.divide_with_remainder (b); a = b; b = a_qr.second; } return a; } void polynomial::show_self () const { unsigned first = 1; for (set_const_iter i = coeffs; i; i ++) { unsigned e = i.val (); if (first) first = 0; else printf (" + "); if (e == 0) printf ("1"); else { if (e == 1) printf ("x"); else printf ("x^%d", e); } } if (first) printf ("0"); }