use crate::polynomial::Polynomial;
#[derive(Debug, Clone)]
pub struct SugaredPolynomial<P> {
pub poly: Polynomial<P>,
pub sugar: usize,
}
impl<P: Clone> SugaredPolynomial<P> {
pub fn new(poly: Polynomial<P>) -> Self {
let sugar = total_degree(&poly);
Self { poly, sugar }
}
}
impl<P: PartialEq + Eq> PartialEq for SugaredPolynomial<P> {
fn eq(&self, other: &Self) -> bool {
self.poly == other.poly && self.sugar == other.sugar
}
}
impl<P: PartialEq + Eq> Eq for SugaredPolynomial<P> {}
impl<P: PartialEq + Eq> Ord for SugaredPolynomial<P> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.sugar.cmp(&other.sugar)
}
}
impl<P: PartialEq + Eq> PartialOrd for SugaredPolynomial<P> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
fn total_degree<P>(poly: &Polynomial<P>) -> usize {
poly.terms
.iter()
.map(|t| {
t.monomial
.exponents
.iter()
.map(|&e| e as usize)
.sum::<usize>()
})
.max()
.unwrap_or(0)
}
pub fn select_next_by_sugar<P: Clone>(
queue: &mut Vec<SugaredPolynomial<P>>,
) -> Option<SugaredPolynomial<P>> {
if queue.is_empty() {
None
} else {
let min_idx = queue
.iter()
.enumerate()
.min_by_key(|(_, sp)| sp.sugar)
.map(|(i, _)| i)?;
Some(queue.remove(min_idx))
}
}