Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pub mod traits {
- //////////////// generated using following macro:
- //
- // #[macro_export]
- // macro_rules! bundle_traits {
- // ( $trait_name:ident, $($traits:path),+ ) => {
- // trait $trait_name: $($traits +)+ {}
- // impl<T: $($traits +)+> $trait_name for T {}
- // };
- //
- // ( pub $trait_name:ident, $($traits:path),+ ) => {
- // pub trait $trait_name: $($traits +)+ {}
- // impl<T: $($traits +)+> $trait_name for T {}
- // };
- // }
- //
- //////////////// used as:
- //
- // bundle_traits!(
- // pub Numeric,
- // Copy,
- // Default,
- // std::ops::Add<Output = Self>,
- // std::ops::Sub<Output = Self>,
- // std::ops::Mul<Output = Self>,
- // std::ops::Div<Output = Self>,
- // std::ops::Rem<Output = Self>,
- // std::ops::Neg<Output = Self>,
- // num::One,
- // num::Zero,
- // std::fmt::Debug
- // );
- // bundle_traits!(
- // pub NumericExtended,
- // Numeric,
- // Ord,
- // PartialEq,
- // PartialOrd,
- // std::ops::AddAssign,
- // std::ops::SubAssign,
- // std::ops::MulAssign,
- // std::ops::DivAssign,
- // std::ops::RemAssign,
- // std::ops::ShlAssign<u32>,
- // std::ops::ShrAssign<u32>,
- // std::ops::BitAndAssign,
- // std::ops::BitOrAssign,
- // std::ops::BitXorAssign,
- // std::ops::Not,
- // std::ops::Shl<u32, Output = Self>,
- // std::ops::Shr<u32, Output = Self>,
- // std::ops::BitAnd<Output = Self>,
- // std::ops::BitOr<Output = Self>,
- // std::ops::BitXor<Output = Self>,
- // num::traits::Pow<u32, Output = Self>,
- // From<u8>
- // );
- //
- ///////////////// expand code using "cargo expand"
- //
- //////////////// OUTPUT:
- pub trait Numeric:
- Copy
- + Default
- + std::ops::Add<Output = Self>
- + std::ops::Sub<Output = Self>
- + std::ops::Mul<Output = Self>
- + std::ops::Div<Output = Self>
- + std::ops::Rem<Output = Self>
- + std::ops::Neg<Output = Self>
- + num::One
- + num::Zero
- + std::fmt::Debug
- {
- }
- impl<
- T: Copy
- + Default
- + std::ops::Add<Output = Self>
- + std::ops::Sub<Output = Self>
- + std::ops::Mul<Output = Self>
- + std::ops::Div<Output = Self>
- + std::ops::Rem<Output = Self>
- + std::ops::Neg<Output = Self>
- + num::One
- + num::Zero
- + std::fmt::Debug,
- > Numeric for T
- {
- }
- pub trait NumericExtended:
- Numeric
- + Ord
- + PartialEq
- + PartialOrd
- + std::ops::AddAssign
- + std::ops::SubAssign
- + std::ops::MulAssign
- + std::ops::DivAssign
- + std::ops::RemAssign
- + std::ops::ShlAssign<u32>
- + std::ops::ShrAssign<u32>
- + std::ops::BitAndAssign
- + std::ops::BitOrAssign
- + std::ops::BitXorAssign
- + std::ops::Not
- + std::ops::Shl<u32, Output = Self>
- + std::ops::Shr<u32, Output = Self>
- + std::ops::BitAnd<Output = Self>
- + std::ops::BitOr<Output = Self>
- + std::ops::BitXor<Output = Self>
- + num::traits::Pow<u32, Output = Self>
- + From<u8>
- {
- }
- impl<
- T: Numeric
- + Ord
- + PartialEq
- + PartialOrd
- + std::ops::AddAssign
- + std::ops::SubAssign
- + std::ops::MulAssign
- + std::ops::DivAssign
- + std::ops::RemAssign
- + std::ops::ShlAssign<u32>
- + std::ops::ShrAssign<u32>
- + std::ops::BitAndAssign
- + std::ops::BitOrAssign
- + std::ops::BitXorAssign
- + std::ops::Not
- + std::ops::Shl<u32, Output = Self>
- + std::ops::Shr<u32, Output = Self>
- + std::ops::BitAnd<Output = Self>
- + std::ops::BitOr<Output = Self>
- + std::ops::BitXor<Output = Self>
- + num::traits::Pow<u32, Output = Self>
- + From<u8>,
- > NumericExtended for T
- {
- }
- }
- // use vectra::traits::{Numeric, NumericExtended};
- use traits::{Numeric, NumericExtended};
- #[derive(Clone, Debug)]
- pub struct Polynomial<T: Numeric> {
- degree: usize,
- coefficients: Vec<T>,
- }
- impl<T: Numeric> Default for Polynomial<T> {
- fn default() -> Self {
- Self {
- degree: 0,
- coefficients: vec![T::zero(); 1],
- }
- }
- }
- impl<T: Numeric> Polynomial<T> {
- pub fn new() -> Self {
- Self::default()
- }
- pub fn from_coefficients(coefficients: Vec<T>) -> Self {
- let degree: usize = coefficients.len() - 1;
- Self {
- degree,
- coefficients,
- }
- }
- pub fn degree(&self) -> usize {
- self.degree
- }
- pub fn coefficients(&self) -> &Vec<T> {
- &self.coefficients
- }
- pub fn get_degree(&self) -> usize {
- self.degree
- }
- pub fn get_coefficient(&self, degree: usize) -> T {
- if degree > self.degree {
- T::zero()
- } else {
- self.coefficients[degree]
- }
- }
- pub fn get_coefficients(&self) -> &Vec<T> {
- &self.coefficients
- }
- pub fn set_degree(&mut self, degree: usize) {
- if degree > self.degree {
- self.degree = degree;
- self.coefficients.resize(degree + 1, T::zero());
- }
- }
- pub fn set_coefficient(&mut self, degree: usize, coefficient: T) {
- self.set_degree(degree);
- self.coefficients[degree] = coefficient;
- }
- }
- impl<T: NumericExtended> Polynomial<T> {
- pub fn evaluate(&self, x: T) -> T {
- let mut result: T = T::zero();
- for (i, coefficient) in self.coefficients.iter().enumerate() {
- result = result + *coefficient * x.pow((self.degree - i) as u32);
- }
- result
- }
- }
- impl<T: std::ops::Add<Output = T> + Numeric> Polynomial<T> {
- pub fn add(&self, other: &Self) -> Self {
- let mut result: Polynomial<T> = Self::new();
- result.set_degree(self.degree.max(other.degree));
- for i in 0..=result.degree {
- result.set_coefficient(i, self.get_coefficient(i) + other.get_coefficient(i));
- }
- result
- }
- }
- impl<T: std::ops::Sub<Output = T> + Numeric> Polynomial<T> {
- pub fn sub(&self, other: &Self) -> Self {
- let mut result: Polynomial<T> = Self::new();
- result.set_degree(self.degree.max(other.degree));
- for i in 0..=result.degree {
- result.set_coefficient(i, self.get_coefficient(i) - other.get_coefficient(i));
- }
- result
- }
- }
- impl<T: std::ops::Mul<Output = T> + Numeric> Polynomial<T> {
- pub fn mul(&self, other: &Self) -> Self {
- let mut result: Polynomial<T> = Self::new();
- result.set_degree(self.degree * other.degree);
- for i in 0..=self.degree {
- for j in 0..=other.degree {
- result.set_coefficient(
- i + j,
- result.get_coefficient(i + j)
- + self.get_coefficient(i) * other.get_coefficient(j),
- );
- }
- }
- result
- }
- }
- impl<T: std::fmt::Display + Numeric> Polynomial<T> {
- pub fn display(&self) {
- let mut formatted_string = String::new();
- for (i, coefficient) in self.coefficients.iter().enumerate() {
- if i == 0 {
- formatted_string.push_str(&format!("{}", coefficient));
- } else {
- formatted_string.push_str(&format!(" + {}x^{}", coefficient, i));
- }
- }
- println!("{}", formatted_string);
- }
- }
- impl<T: std::fmt::Display + NumericExtended> std::fmt::Display for Polynomial<T> {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- let mut formatted_string = String::new();
- let mut is_first_term = true;
- for (degree, coefficient) in self.coefficients.iter().enumerate().rev() {
- if coefficient != &T::zero() {
- let mut coefficient = *coefficient;
- let is_neg = coefficient < T::zero();
- let sign = if is_neg {
- coefficient = -coefficient;
- "- "
- } else {
- "+ "
- };
- if is_first_term {
- if is_neg {
- formatted_string.push_str(sign);
- }
- is_first_term = false;
- } else {
- formatted_string.push(' ');
- formatted_string.push_str(sign);
- }
- if degree == 0 {
- formatted_string.push_str(&format!("{}", coefficient));
- } else if degree == 1 {
- formatted_string.push_str(&format!("{}x", coefficient));
- } else {
- formatted_string.push_str(&format!("{}x^{}", coefficient, degree));
- }
- }
- }
- write!(f, "{}", formatted_string)
- }
- }
- fn main() {
- let mut p1: Polynomial<i32> = Polynomial::new();
- let mut p2: Polynomial<i32> = Polynomial::new();
- p1.set_coefficient(2, 3);
- p1.set_coefficient(1, 2);
- p1.set_coefficient(0, 1);
- p2.set_coefficient(3, 4);
- p2.set_coefficient(2, 3);
- p2.set_coefficient(1, 2);
- p2.set_coefficient(0, 1);
- println!("p1: {}", p1);
- println!("p2: {}", p2);
- let p3 = p1.add(&p2);
- let p4 = p1.sub(&p2);
- let p5 = p1.mul(&p2);
- println!("p1 + p2: {}", p3);
- println!("p1 - p2: {}", p4);
- println!("p1 * p2: {}", p5);
- let a = p1 + p1; // cannot add `Polynomial<i32>` to `Polynomial<i32>`rustc Click for full compiler diagnostic
- // main.rs(350, 13): Polynomial<i32>
- // main.rs(350, 18): Polynomial<i32>
- // main.rs(150, 1): an implementation of `std::ops::Add` might be missing for `Polynomial<i32>`
- // arith.rs(76, 1): the trait `std::ops::Add` must be implemented
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement