Решение на Polynomial от Емилиан Станков
Към профила на Емилиан Станков
Резултати
- 9 точки от тестове
- 0 бонус точки
- 9 точки общо
- 9 успешни тест(а)
- 6 неуспешни тест(а)
Код
use std::ops::Mul;
use std::ops::Div;
use std::ops::Add;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>,
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
let mut result = 0.0;
for (i, coef) in self.coefs.iter().enumerate() {
result += point.0.powi(i as i32) * coef;
}
(result - point.1).abs() < 1e-10
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut x_values: Vec<f64> = vec![];
for (_i, point) in points.iter().enumerate() {
if x_values.contains(&point.0) {
return None;
}
x_values.push(point.0);
}
let mut lagrange_coefs: Vec<f64> = vec![];
for (i, _point) in points.iter().enumerate() {
lagrange_coefs.push(0.0);
lagrange_coefs[i] += points[i].1 * Self::lj(i, points.clone());
}
Some(Polynomial::from(lagrange_coefs))
}
fn lj(j: usize, points: Vec<(f64, f64)>) -> f64 {
let mut result = 1.0;
for (i, point) in points.iter().enumerate() {
result *= (point.0 - points[i].0) / (points[j].0 - points[i].0);
}
result
}
fn compare(&self, rhs: &Self) -> (Vec<f64>, Vec<f64>) {
let mut larger = &self.coefs;
let mut smaller = &rhs.coefs;
if rhs.coefs.len() > self.coefs.len() {
larger = &rhs.coefs;
smaller = &self.coefs;
}
(larger.to_vec(), smaller.to_vec())
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
Polynomial { coefs: coefs }
}
}
impl Default for Polynomial {
fn default() -> Self {
Polynomial { coefs: vec![0.0] }
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
let (larger, smaller) = self.compare(rhs);
for (i, coef) in larger.iter().enumerate() {
if i >= smaller.len() {
if coef != &(0.0 as f64) {
return false;
}
} else {
if (coef - smaller[i]).abs() >= 1e-10 {
return false;
}
}
}
true
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
let coefs: Vec<f64> = self.coefs.iter().map(|coef| coef * rhs).collect();
Polynomial::from(coefs)
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
let coefs: Vec<f64> = self.coefs.iter().map(|coef| coef / rhs).collect();
Polynomial::from(coefs)
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let mut result_coefs: Vec<f64> = vec![];
for (i, coefi) in self.coefs.iter().enumerate() {
for (j, coefj) in rhs.coefs.iter().enumerate() {
result_coefs.push(0.0);
let old_value = result_coefs[i + j];
result_coefs[i + j] = old_value + coefi * coefj;
}
}
result_coefs.reverse();
Polynomial::from(result_coefs)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let mut result_coefs: Vec<f64> = vec![];
let (larger, smaller) = self.compare(&rhs);
for (i, coef) in larger.iter().enumerate() {
if i >= smaller.len() {
result_coefs.push(coef.clone());
} else {
result_coefs.push(coef + smaller[i]);
}
}
result_coefs.reverse();
Polynomial::from(result_coefs)
}
}
Лог от изпълнението
Compiling solution v0.1.0 (file:///tmp/d20171121-6053-q8z44v/solution) Finished dev [unoptimized + debuginfo] target(s) in 5.1 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 ... FAILED 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 ... FAILED test solution_test::test_lagrange_poly_2 ... FAILED test solution_test::test_lagrange_poly_err_eq_x ... ok test solution_test::test_mul_poly ... ok test solution_test::test_mul_poly_f64 ... FAILED test solution_test::test_mul_poly_f64_zero ... ok test solution_test::test_mul_poly_zero_one ... ok failures: ---- solution_test::test_arithmetic_properties stdout ---- thread 'solution_test::test_arithmetic_properties' panicked at 'assertion failed: `(left == right)` left: `Polynomial { coefs: [1, 0, -1] }`, right: `Polynomial { coefs: [0] }`', tests/solution_test.rs:125:4 note: Run with `RUST_BACKTRACE=1` for a backtrace. ---- solution_test::test_div_poly_f64 stdout ---- thread 'solution_test::test_div_poly_f64' panicked at 'assertion failed: `(left == right)` left: `Polynomial { coefs: [-0.16666666666666666, 0.3333333333333333, -0.8333333333333334] }`, right: `Polynomial { coefs: [-0.8333333333333334, 0.3333333333333333, -0.16666666666666666] }`', tests/solution_test.rs:76:4 ---- solution_test::test_fp_comparison stdout ---- thread 'solution_test::test_fp_comparison' panicked at 'assertion failed: `(left == right)` left: `Polynomial { coefs: [3, 0.00000000000000000000000030000000000000002] }`, right: `Polynomial { coefs: [0.0000000000000000000000003, 3] }`', tests/solution_test.rs:32:4 ---- solution_test::test_lagrange_poly_1 stdout ---- thread 'solution_test::test_lagrange_poly_1' panicked at 'assertion failed: valid_lp(&poly, &points)', tests/solution_test.rs:215:4 ---- solution_test::test_lagrange_poly_2 stdout ---- thread 'solution_test::test_lagrange_poly_2' panicked at 'assertion failed: valid_lp(&poly.unwrap(), &points)', tests/solution_test.rs:233:4 ---- solution_test::test_mul_poly_f64 stdout ---- thread 'solution_test::test_mul_poly_f64' panicked at 'assertion failed: `(left == right)` left: `Polynomial { coefs: [5, -10, 25] }`, right: `Polynomial { coefs: [25, -10, 5] }`', tests/solution_test.rs:55:4 failures: solution_test::test_arithmetic_properties solution_test::test_div_poly_f64 solution_test::test_fp_comparison solution_test::test_lagrange_poly_1 solution_test::test_lagrange_poly_2 solution_test::test_mul_poly_f64 test result: FAILED. 9 passed; 6 failed; 0 ignored; 0 measured; 0 filtered out error: test failed, to rerun pass '--test solution_test'
История (3 версии и 1 коментар)
Емилиан качи решение на 14.11.2017 23:32 (преди почти 8 години)
use std::ops::Mul;
use std::ops::Div;
use std::ops::Add;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>,
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
let mut result = 0.0;
for (i, coef) in self.coefs.iter().enumerate() {
result += point.0.powi(i as i32) * coef;
}
(result - point.1).abs() < 1e-10
}
pub fn interpolate(_points: Vec<(f64, f64)>) -> Option<Self> {
None //TODO
}
+
+ fn compare(&self, rhs: &Self) -> (Vec<f64>, Vec<f64>) {
+ let mut larger = &self.coefs;
+ let mut smaller = &rhs.coefs;
+ if rhs.coefs.len() > self.coefs.len() {
+ larger = &rhs.coefs;
+ smaller = &self.coefs;
+ }
+ (larger.to_vec(), smaller.to_vec())
+ }
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
Polynomial { coefs: coefs }
}
}
impl Default for Polynomial {
fn default() -> Self {
Polynomial { coefs: vec![0.0] }
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
- let mut larger = &self.coefs;
- let mut smaller = &rhs.coefs;
- if rhs.coefs.len() > self.coefs.len() {
- larger = &rhs.coefs;
- smaller = &self.coefs;
- }
+ let (larger, smaller) = self.compare(rhs);
for (i, coef) in larger.iter().enumerate() {
if i >= smaller.len() {
if coef != &(0.0 as f64) {
return false;
}
} else {
if (coef - smaller[i]).abs() >= 1e-10 {
return false;
}
}
}
true
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
let coefs: Vec<f64> = self.coefs.iter().map(|coef| coef * rhs).collect();
Polynomial::from(coefs)
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
let coefs: Vec<f64> = self.coefs.iter().map(|coef| coef / rhs).collect();
Polynomial::from(coefs)
}
}
impl Mul for Polynomial {
type Output = Polynomial;
- fn mul(self, _rhs: Polynomial) -> Self::Output {
- self //TODO
+ fn mul(self, rhs: Polynomial) -> Self::Output {
+ let mut result_coefs: Vec<f64> = vec![];
+ for (i, coefi) in self.coefs.iter().enumerate() {
+ for (j, coefj) in rhs.coefs.iter().enumerate() {
+ result_coefs.push(0.0);
+ let old_value = result_coefs[i + j];
+ result_coefs[i + j] = old_value + coefi * coefj;
+ }
+ }
+ result_coefs.reverse();
+ Polynomial::from(result_coefs)
}
}
impl Add for Polynomial {
type Output = Polynomial;
- fn add(self, _rhs: Polynomial) -> Self::Output {
- self //TODO
+ fn add(self, rhs: Polynomial) -> Self::Output {
+ let mut result_coefs: Vec<f64> = vec![];
+ let (larger, smaller) = self.compare(&rhs);
+ for (i, coef) in larger.iter().enumerate() {
+ if i >= smaller.len() {
+ result_coefs.push(coef.clone());
+ } else {
+ result_coefs.push(coef + smaller[i]);
+ }
+ }
+ result_coefs.reverse();
+ Polynomial::from(result_coefs)
}
-}
+}
Емилиан качи решение на 15.11.2017 00:35 (преди почти 8 години)
use std::ops::Mul;
use std::ops::Div;
use std::ops::Add;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>,
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
let mut result = 0.0;
for (i, coef) in self.coefs.iter().enumerate() {
result += point.0.powi(i as i32) * coef;
}
(result - point.1).abs() < 1e-10
}
- pub fn interpolate(_points: Vec<(f64, f64)>) -> Option<Self> {
- None //TODO
+ pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
+ let mut x_values: Vec<f64> = vec![];
+ for (_i, point) in points.iter().enumerate() {
+ if x_values.contains(&point.0) {
+ return None;
+ }
+ x_values.push(point.0);
+ }
+
+ let mut lagrange_coefs: Vec<f64> = vec![];
+ for (i, _point) in points.iter().enumerate() {
+ lagrange_coefs.push(0.0);
+ lagrange_coefs[i] += points[i].1 * Self::lj(i, points.clone());
+ }
+
+ Some(Polynomial::from(lagrange_coefs))
+ }
+
+ fn lj(j: usize, points: Vec<(f64, f64)>) -> f64 {
+ let mut result = 1.0;
+ for (i, point) in points.iter().enumerate() {
+ result *= (point.0 - points[i].0) / (points[j].0 - points[i].0);
+ }
+ result
}
fn compare(&self, rhs: &Self) -> (Vec<f64>, Vec<f64>) {
let mut larger = &self.coefs;
let mut smaller = &rhs.coefs;
if rhs.coefs.len() > self.coefs.len() {
larger = &rhs.coefs;
smaller = &self.coefs;
}
(larger.to_vec(), smaller.to_vec())
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
Polynomial { coefs: coefs }
}
}
impl Default for Polynomial {
fn default() -> Self {
Polynomial { coefs: vec![0.0] }
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
let (larger, smaller) = self.compare(rhs);
for (i, coef) in larger.iter().enumerate() {
if i >= smaller.len() {
if coef != &(0.0 as f64) {
return false;
}
} else {
if (coef - smaller[i]).abs() >= 1e-10 {
return false;
}
}
}
true
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
let coefs: Vec<f64> = self.coefs.iter().map(|coef| coef * rhs).collect();
Polynomial::from(coefs)
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
let coefs: Vec<f64> = self.coefs.iter().map(|coef| coef / rhs).collect();
Polynomial::from(coefs)
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let mut result_coefs: Vec<f64> = vec![];
for (i, coefi) in self.coefs.iter().enumerate() {
for (j, coefj) in rhs.coefs.iter().enumerate() {
result_coefs.push(0.0);
let old_value = result_coefs[i + j];
result_coefs[i + j] = old_value + coefi * coefj;
}
}
result_coefs.reverse();
Polynomial::from(result_coefs)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let mut result_coefs: Vec<f64> = vec![];
let (larger, smaller) = self.compare(&rhs);
for (i, coef) in larger.iter().enumerate() {
if i >= smaller.len() {
result_coefs.push(coef.clone());
} else {
result_coefs.push(coef + smaller[i]);
}
}
result_coefs.reverse();
Polynomial::from(result_coefs)
}
}
Пробвай да запълниш тестовете с малко по-сложни примери. Напиши си собствени примери, със същите полиноми, опитай комбинации от операции и виж дали връщат каквото очакваш.