Решение на Polynomial от Иван Велков
Резултати
- 13 точки от тестове
- 0 бонус точки
- 13 точки общо
- 13 успешни тест(а)
- 2 неуспешни тест(а)
Код
use std::ops::Mul;
use std::ops::Add;
use std::ops::Div;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs_: Vec<f64>,
}
static DELTA : f64 = 1e-10;
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
let mut res = 0.0_f64;
for (i, x) in self.coefs_.iter().enumerate() {
res += x * point.0.powi(i as i32);
}
(res - point.1).abs() < DELTA
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut result = vec![0.0_f64; points.len()];
for curpoint in points.iter() {
let mut tmpcoefs = vec![0.0_f64; points.len()];
tmpcoefs[0] = curpoint.1;
let mut prod = 1.0_f64;
let mut cnt = 0;
for point in points.iter()
{
if (curpoint.0 - point.0).abs() < DELTA {
cnt += 1;
if cnt > 1 {
return None
}
continue;
}
prod *= curpoint.0 - point.0;
let mut precedent = 0.0_f64;
for i in tmpcoefs.iter_mut() {
let newres = *i * (-point.0) + precedent;
precedent = *i;
*i = newres;
}
}
for (oldcoef, add) in result.iter_mut().zip(tmpcoefs.iter()) {
*oldcoef += *add / prod;
}
}
result.reverse();
Some(Polynomial::from(result))
}
}
impl From<Vec<f64>> for Polynomial {
fn from(coefs: Vec<f64>) -> Self {
let mut tmp: Vec<f64> = coefs.into_iter().skip_while(|x| *x == 0.0).collect::<Vec<_>>();
if tmp.len() == 0
{
tmp = vec![0.0];
}
tmp.reverse();
Self{
coefs_: tmp,
}
}
}
impl Default for Polynomial {
fn default() -> Self {
Self{
coefs_: vec![0.0],
}
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
self.coefs_.iter().zip(rhs.coefs_.iter()).all(|(a, b)| (a - b).abs() < DELTA)
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output{
if (rhs - 0.0).abs() < DELTA {
return Polynomial::default();
}
Polynomial{coefs_: self.coefs_.iter().map(|&x| x * rhs).collect::<Vec<_>>()}
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
if (rhs - 0.0).abs() < DELTA {
panic!("Division by zero");
}
Polynomial{coefs_: self.coefs_.iter().map(|&x| x * rhs).collect::<Vec<_>>()}
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let newsize = self.coefs_.len() + rhs.coefs_.len();
let mut newcoefs = vec![0.0_f64; newsize];
for (i, x) in self.coefs_.iter().enumerate() {
for (j, y) in rhs.coefs_.iter().enumerate()
{
newcoefs[i + j] += x * y;
}
}
newcoefs.reverse();
Polynomial::from(newcoefs)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let max = std::cmp::max(self.coefs_.len(),rhs.coefs_.len());
let mut newcoefs = vec![0.0_f64; max];
for (i, j) in newcoefs.iter_mut().zip(rhs.coefs_.iter()) {
*i += *j;
}
for (i, j) in newcoefs.iter_mut().zip(self.coefs_.iter()) {
*i += *j;
}
newcoefs.reverse();
Polynomial::from(newcoefs)
}
}
Лог от изпълнението
Compiling solution v0.1.0 (file:///tmp/d20171121-6053-1lzx7yc/solution) Finished dev [unoptimized + debuginfo] target(s) in 5.41 secs Running target/debug/deps/solution-200db9172ea1f728 running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Running target/debug/deps/solution_test-e3c9eb714e09105e running 15 tests test solution_test::test_add_poly ... ok test solution_test::test_add_poly_zero_one ... ok test solution_test::test_arithmetic_properties ... ok test solution_test::test_create_poly ... ok test solution_test::test_div_poly_f64 ... FAILED test solution_test::test_div_poly_f64_zero ... ok test solution_test::test_fp_comparison ... FAILED test solution_test::test_has_point ... ok test solution_test::test_lagrange_poly_1 ... ok test solution_test::test_lagrange_poly_2 ... ok test solution_test::test_lagrange_poly_err_eq_x ... ok test solution_test::test_mul_poly ... ok test solution_test::test_mul_poly_f64 ... ok test solution_test::test_mul_poly_f64_zero ... ok test solution_test::test_mul_poly_zero_one ... ok failures: ---- solution_test::test_div_poly_f64 stdout ---- thread 'solution_test::test_div_poly_f64' panicked at 'assertion failed: `(left == right)` left: `Polynomial { coefs_: [-30, 12, -6] }`, right: `Polynomial { coefs_: [-0.8333333333333334, 0.3333333333333333, -0.16666666666666666] }`', tests/solution_test.rs:76:4 note: Run with `RUST_BACKTRACE=1` for a backtrace. ---- solution_test::test_fp_comparison stdout ---- thread 'solution_test::test_fp_comparison' panicked at 'assertion failed: `(left == right)` left: `Polynomial { coefs_: [0.00000000000000000000000005, 0.5] }`, right: `Polynomial { coefs_: [0.0000000000000000000000002, 2] }`', tests/solution_test.rs:33:4 failures: solution_test::test_div_poly_f64 solution_test::test_fp_comparison test result: FAILED. 13 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out error: test failed, to rerun pass '--test solution_test'
История (2 версии и 0 коментара)
Иван качи решение на 20.11.2017 16:05 (преди почти 8 години)
use std::ops::Mul;
use std::ops::Add;
use std::ops::Div;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs_: Vec<f64>,
}
static DELTA : f64 = 1e-10;
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
let mut res = 0.0_f64;
for (i, x) in self.coefs_.iter().enumerate() {
res += x * point.0.powi(i as i32);
}
(res - point.1).abs() < DELTA
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut result = vec![0.0_f64; points.len()];
for curpoint in points.iter() {
let mut tmpcoefs = vec![0.0_f64; points.len()];
tmpcoefs[0] = curpoint.1;
let mut prod = 1.0_f64;
let mut cnt = 0;
for point in points.iter()
{
if (curpoint.0 - point.0).abs() < DELTA {
cnt += 1;
if cnt > 1 {
return None
}
continue;
}
prod *= curpoint.0 - point.0;
let mut precedent = 0.0_f64;
for i in tmpcoefs.iter_mut() {
let newres = *i * (-point.0) + precedent;
precedent = *i;
*i = newres;
}
}
for (oldcoef, add) in result.iter_mut().zip(tmpcoefs.iter()) {
*oldcoef += *add / prod;
}
}
result.reverse();
Some(Polynomial::from(result))
}
}
impl From<Vec<f64>> for Polynomial {
fn from(coefs: Vec<f64>) -> Self {
let mut tmp: Vec<f64> = coefs.into_iter().skip_while(|x| *x == 0.0).collect::<Vec<_>>();
if tmp.len() == 0
{
tmp = vec![0.0];
}
tmp.reverse();
Self{
coefs_: tmp,
}
}
}
impl Default for Polynomial {
fn default() -> Self {
Self{
coefs_: vec![0.0],
}
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
self.coefs_.iter().zip(rhs.coefs_.iter()).all(|(a, b)| (a - b).abs() < DELTA)
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output{
if (rhs - 0.0).abs() < DELTA {
return Polynomial::default();
}
Polynomial{coefs_: self.coefs_.iter().map(|&x| x * rhs).collect::<Vec<_>>()}
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
if (rhs - 0.0).abs() < DELTA {
- // TO DO
- return Polynomial::default();
+ panic!("Division by zero");
}
Polynomial{coefs_: self.coefs_.iter().map(|&x| x * rhs).collect::<Vec<_>>()}
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let newsize = self.coefs_.len() + rhs.coefs_.len();
let mut newcoefs = vec![0.0_f64; newsize];
for (i, x) in self.coefs_.iter().enumerate() {
for (j, y) in rhs.coefs_.iter().enumerate()
{
newcoefs[i + j] += x * y;
}
}
newcoefs.reverse();
Polynomial::from(newcoefs)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let max = std::cmp::max(self.coefs_.len(),rhs.coefs_.len());
let mut newcoefs = vec![0.0_f64; max];
for (i, j) in newcoefs.iter_mut().zip(rhs.coefs_.iter()) {
*i += *j;
}
for (i, j) in newcoefs.iter_mut().zip(self.coefs_.iter()) {
*i += *j;
}
newcoefs.reverse();
Polynomial::from(newcoefs)
}
}