Решение на Polynomial от Исмаил Алиджиков
Към профила на Исмаил Алиджиков
Резултати
- 14 точки от тестове
- 0 бонус точки
- 14 точки общо
- 14 успешни тест(а)
- 1 неуспешни тест(а)
Код
Лог от изпълнението
Compiling solution v0.1.0 (file:///tmp/d20171121-6053-4rs5pp/solution) Finished dev [unoptimized + debuginfo] target(s) in 4.86 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 ... ok test solution_test::test_div_poly_f64_zero ... ok test solution_test::test_fp_comparison ... ok test solution_test::test_has_point ... ok test solution_test::test_lagrange_poly_1 ... ok 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 ... ok test solution_test::test_mul_poly_f64_zero ... ok test solution_test::test_mul_poly_zero_one ... ok failures: ---- 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 note: Run with `RUST_BACKTRACE=1` for a backtrace. failures: solution_test::test_lagrange_poly_2 test result: FAILED. 14 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out error: test failed, to rerun pass '--test solution_test'
История (3 версии и 1 коментар)
Исмаил качи решение на 19.11.2017 14:52 (преди почти 8 години)
use std::ops::{Add, Mul, Div};
use std::cmp::max;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>
-
}
impl Polynomial {
fn new(mut coefs: Vec<f64>) -> Self {
while coefs.last() != None && coefs.last().unwrap().abs() < 1e-10 {
coefs.pop();
}
Polynomial {
coefs: coefs
}
}
pub fn has(&self, point: &(f64, f64)) -> bool {
let evaluation = Polynomial::evaluate(&self, point.0);
(evaluation - point.1).abs() < 1e-10
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut result = Polynomial::default();
for i in 0..points.len() {
let mut limes = Polynomial::from(vec![1.0]);
for j in 0..points.len() {
if i == j {
continue;
} else if points[i].0 == points[j].0 {
return None;
}
limes = limes * (Polynomial::from(vec![points[j].0 * (-1.0), 1.0]) / (points[i].0 - points[j].0));
}
result = result + limes * points[i].1;
}
Some(result)
}
fn evaluate(&self, x: f64) -> f64 {
let mut sum = 0.0;
for (i, item) in self.coefs.iter().enumerate() {
sum += x.powi(i as i32) * item;
}
sum
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
Polynomial::new(coefs)
}
}
impl Default for Polynomial {
fn default() -> Polynomial {
Polynomial::new(vec![])
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
if self.coefs.len() != rhs.coefs.len() {
return false;
}
for i in 0..self.coefs.len() {
let are_eq = (self.coefs[i] - rhs.coefs[i]).abs() < 1e-10;
if !are_eq {
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(|c| c * rhs).collect();
Polynomial::new(coefs)
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
let coefs: Vec<f64> = self.coefs.iter().map(|c| c / rhs).collect();
Polynomial::new(coefs)
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let len = self.coefs.len() + rhs.coefs.len();
if len == 0 {
return Polynomial::default();
}
let mut coefs = vec![0.0; len - 1];
for i in 0..self.coefs.len() {
for j in 0..rhs.coefs.len() {
coefs[i + j] += self.coefs[i] * rhs.coefs[j];
}
}
Polynomial::new(coefs)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let len = max(self.coefs.len(), rhs.coefs.len());
let mut coefs = vec!(0.0; len);
for i in 0..self.coefs.len() {
coefs[i] = self.coefs[i];
}
for i in 0..rhs.coefs.len() {
coefs[i] += rhs.coefs[i];
}
Polynomial::new(coefs)
}
}
Исмаил качи решение на 19.11.2017 14:56 (преди почти 8 години)
use std::ops::{Add, Mul, Div};
use std::cmp::max;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>
}
impl Polynomial {
fn new(mut coefs: Vec<f64>) -> Self {
while coefs.last() != None && coefs.last().unwrap().abs() < 1e-10 {
coefs.pop();
}
Друг начин, по който можеш да постигнеш същото, може би малко по-елегантен:
fn new(mut coefs: Vec<f64>) -> Self {
if let Some(non_zero_position) = coefs.iter().rposition(|x| x.abs() > 1e-10) {
coefs.truncate(non_zero_position + 1);
Polynomial { coefs: coefs }
} else {
Polynomial { coefs: vec![0.0] }
}
}
Ако си направиш помощна функцийка, not_zero
, може края на условието да изглежда като .rposition(not_zero)
. Пак е малко тежичко, но не е тривиално с ownership правилата хем да вземеш ref към последния елемент, хем да го pop-неш в един и също scope :). Досадно, но какво да се прави.
Polynomial {
coefs: coefs
}
}
pub fn has(&self, point: &(f64, f64)) -> bool {
let evaluation = Polynomial::evaluate(&self, point.0);
(evaluation - point.1).abs() < 1e-10
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut result = Polynomial::default();
for i in 0..points.len() {
let mut limes = Polynomial::from(vec![1.0]);
for j in 0..points.len() {
if i == j {
continue;
} else if points[i].0 == points[j].0 {
return None;
}
limes = limes * (Polynomial::from(vec![points[j].0 * (-1.0), 1.0]) / (points[i].0 - points[j].0));
}
result = result + limes * points[i].1;
}
Some(result)
}
fn evaluate(&self, x: f64) -> f64 {
let mut sum = 0.0;
- for (i, item) in self.coefs.iter().enumerate() {
- sum += x.powi(i as i32) * item;
+ for i in 0..self.coefs.len() {
+ sum += x.powi(i as i32) * self.coefs[i];
}
sum
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
Polynomial::new(coefs)
}
}
impl Default for Polynomial {
fn default() -> Polynomial {
Polynomial::new(vec![])
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
if self.coefs.len() != rhs.coefs.len() {
return false;
}
for i in 0..self.coefs.len() {
let are_eq = (self.coefs[i] - rhs.coefs[i]).abs() < 1e-10;
if !are_eq {
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(|c| c * rhs).collect();
Polynomial::new(coefs)
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
let coefs: Vec<f64> = self.coefs.iter().map(|c| c / rhs).collect();
Polynomial::new(coefs)
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let len = self.coefs.len() + rhs.coefs.len();
if len == 0 {
return Polynomial::default();
}
let mut coefs = vec![0.0; len - 1];
for i in 0..self.coefs.len() {
for j in 0..rhs.coefs.len() {
coefs[i + j] += self.coefs[i] * rhs.coefs[j];
}
}
Polynomial::new(coefs)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let len = max(self.coefs.len(), rhs.coefs.len());
let mut coefs = vec!(0.0; len);
for i in 0..self.coefs.len() {
coefs[i] = self.coefs[i];
}
for i in 0..rhs.coefs.len() {
coefs[i] += rhs.coefs[i];
}
Polynomial::new(coefs)
}
}
Друг начин, по който можеш да постигнеш същото, може би малко по-елегантен:
Ако си направиш помощна функцийка,
not_zero
, може края на условието да изглежда като.rposition(not_zero)
. Пак е малко тежичко, но не е тривиално с ownership правилата хем да вземеш ref към последния елемент, хем да го pop-неш в един и също scope :). Досадно, но какво да се прави.