use {
crate::traits::Required,
rand::{thread_rng, Rng},
std::fmt,
};
pub struct Monomial<T: Required> {
exponents: Vec<T>,
coefficient: T,
}
impl<T: Required> Monomial<T> {
#[cfg(test)]
pub(crate) fn new(exponents: Vec<T>, coefficient: T) -> Self {
Self {
exponents,
coefficient,
}
}
pub fn generate(mut exponent_limit: T, coefficient_limit: T) -> Self {
let mut rng = thread_rng();
let coefficient = rng.gen_range(T::one(), coefficient_limit);
let mut exponents: Vec<T> = Vec::new();
while exponent_limit > T::one() {
let exp = rng.gen_range(T::zero(), exponent_limit);
exponents.push(exp);
exponent_limit -= exp;
}
Self {
exponents,
coefficient,
}
}
}
impl<T: Required> fmt::Display for Monomial<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut flag = false;
if self.coefficient == T::zero() {
return write!(f, "{}", self.coefficient);
} else if self.coefficient == T::one() {
flag = true;
} else {
write!(f, "{}", self.coefficient)?;
}
for i in 0..self.exponents.len() {
if self.exponents[i] == T::zero() {
} else if self.exponents[i] == T::one() {
flag = false;
write!(f, "x_{{{}}}", (i + 1))?;
} else {
flag = false;
write!(f, "x_{{{}}}^{{{}}}", (i + 1), self.exponents[i])?;
};
}
if flag {
write!(f, "1")
} else {
Ok(())
}
}
}