mod iter; use iter::Iter; use std::fmt; use std::ops::{Add, Sub}; #[derive(PartialEq, Debug, Clone)] pub struct Poly { data: Vec, degree: usize, } impl Poly { pub fn new(data: Vec) -> Poly { if data.len() > 1 { let mut i = data.len() - 1; while data[i] == 0.0 && i > 0 { i -= 1; } Poly { data, degree: i } } else { Poly { data, degree: 0 } } } pub fn degree(&self) -> usize { self.degree } fn iter(&self) -> Iter { Iter::new(self.data.clone(), self.degree()) } pub fn shift(self) -> Poly { let mut r = vec![0.0]; r.append(&mut self.data.clone()); Poly::new(r) } pub fn deriv(&self) -> Poly { let mut data = vec![0.0; self.degree()]; if self.degree() > 0 { for i in 0..self.degree() { data[i] = self.data[i + 1] * (i + 1) as f32; } Poly::new(data) } else { Poly::new(vec![0.0]) } } } impl Add for &Poly { type Output = Poly; fn add(self, other: Self) -> Poly { Poly::new(self.iter().zip(other.iter()).map(|(x, y)| x + y).collect()) } } impl Sub for &Poly { type Output = Poly; fn sub(self, other: Self) -> Poly { Poly::new(self.iter().zip(other.iter()).map(|(x, y)| x - y).collect()) } } impl fmt::Display for &Poly { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut s = String::new(); for i in 0..self.data.len() { s.push_str(&self.data[i].clone().to_string()); if i < self.data.len() - 1 { s.push_str(", "); } } write!(f, "{}", s) } } #[cfg(test)] mod tests { use super::*; #[test] fn shift_test() { let a = Poly::new(vec![1.0, 2.0, 3.0]); assert_eq!(a.shift(), Poly::new(vec![0.0, 1.0, 2.0, 3.0])); } #[test] fn add_test() { let a = Poly::new(vec![1.0]); let b = Poly::new(vec![0.0, 0.0, 0.0, 1.0]); assert_eq!(&a + &b, Poly::new(vec![1.0, 0.0, 0.0, 1.0])); } #[test] fn sub_test() { let a = Poly::new(vec![1.0, 2.0, 3.0]); let b = Poly::new(vec![1.0, 1.0, 1.0]); assert_eq!(&a - &b, Poly::new(vec![0.0, 1.0, 2.0])); } #[test] fn deriv_test() { let p = Poly::new(vec![1.0, 2.0, 3.0, 4.0]); assert_eq!(p.deriv(), Poly::new(vec![2.0, 6.0, 12.0])); } #[test] fn degree_is_five() { let p = Poly::new(vec![0.0, 0.0, 0.0, 0.0, 0.0, 2.0]); assert_eq!(p.degree(), 5); } #[test] fn degree_is_zero() { let p = Poly::new(vec![0.0; 6]); assert_eq!(p.degree(), 0); } }