Решение на Polynomial от Биляна Добрева

Обратно към всички решения

Към профила на Биляна Добрева

Резултати

  • 7 точки от тестове
  • 0 бонус точки
  • 7 точки общо
  • 7 успешни тест(а)
  • 8 неуспешни тест(а)

Код

#[derive(Debug, Clone)]
pub struct Polynomial {
c : Vec<f64>,
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
let mut i = self.c.len()-1;
let mut acc : f64= 0.0;
for &val in self.c.iter() {
acc = acc + val*power(point.0,i);
i = i -1;
}

Различен начин, по който може би може да напишеш това:

for (i, &val) in self.c.iter().rev().enumerate() {
    acc += val * power(point.0, i)
}

Или нещо в тоя дух, поне. Обръщането на итератора с rev е безплатно, понеже имаме вектор.

if (acc - point.1).abs() < 1e-10 {
return true;
}
return false;
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
None
}
}
pub fn power(x : f64,i : usize) -> f64 {
if i == 0 {
return 1.0;
}
return x*power(x,i-1);
}

Има вградена функция, която можеш да ползваш за това, която вероятно ще е по-ефективна: https://doc.rust-lang.org/std/primitive.f64.html#method.powi. Само дето трябва да cast-неш аргумента към i32, но не би било проблем за нас, в случая. Доста голям полином трябва да се направи, за да бъде cast-ването проблем :).

impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
if coefs== vec![0.0] || coefs==vec![] {
return Polynomial{ c : vec![0.0] };
}
coefs = coefs.into_iter().skip_while(|&x| x ==0.0).collect();
return Polynomial{c : coefs};
}
}
impl Default for Polynomial {
fn default() -> Self {
Polynomial{ c : vec![0.0] }
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
let mut v1 : Vec<f64> = self.c.clone();
v1=v1.into_iter().skip_while(|&x| x ==0.0).collect();
let mut v2 : Vec<f64> = rhs.c.clone();
v2=v2.into_iter().skip_while(|&y| y== 0.0).collect();
if v1.len() != v2.len() {
return false;
}
let size = v1.len();
let v3 : Vec<f64> = v1.into_iter().zip(v2).map(|(x,y)| (x-y).abs()).filter(|&x| x<1e-10).collect();
if v3.len()!=size {
return false;
}
else {
return true;
}
}
}
use std::ops::Mul;
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
let mut v1 : Vec<f64> = self.c.clone();
v1 = v1.into_iter().map(|x| rhs*x ).collect();
return Polynomial {c : v1};
}
}
use std::ops::Div;
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
let mut v1 : Vec<f64> = self.c.clone();
v1 = v1.into_iter().map(|x| x/rhs ).collect();
return Polynomial {c : v1};
}
}
use std::ops::Add;
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let mut v1 : Vec<f64>=Polynomial::from(self.c.clone()).c;
let size1=v1.len()-1;
let v2 : Vec<f64>=Polynomial::from(rhs.c.clone()).c;
let size2=v2.len()-1;
if size1>size2{
let mut v3: Vec<f64> = vec![];
let mut i:usize =0;
while i<size1-size2{
v3.push(0.0);
i=i+1;
}
for &val in v2.iter() {
v3.push(val);
}
v1=v1.into_iter().zip(v3).map(|(x,y)| x+y).collect();
}
if size1<size2 {
let mut v3: Vec<f64> = vec![];
let mut i:usize =0;
while i<size2-size1{
v3.push(0.0);
i=i+1;
}
for &val in v1.iter() {
v3.push(val);
}
v1=v1.into_iter().zip(v3).map(|(x,y)| x+y).collect();
}
if size1==size2 {
v1=v1.into_iter().zip(v2).map(|(x,y)| x+y).collect();
}
return Polynomial{ c: v1};
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let v1 : Vec<f64>=Polynomial::from(self.c.clone()).c;
let size1=v1.len()-1;
let v2 : Vec<f64>=Polynomial::from(rhs.c.clone()).c;
let size2=v2.len()-1;
let size = size1+size2;
let mut res = Polynomial::from(vec![0.0]);
let mut i : usize = 0;
let mut j = size-size2;
for &val in v1.iter() {
let p1 = Polynomial::from(v2.clone()) * val ;
let mut v3 :Vec<f64> = vec![];
let mut i1 : usize = 0;
while i1<i{
v3.push(0.0);
i1=i1+1;
}
for &v in p1.c.iter() {
v3.push(v);
}
let mut j1: usize =0;
while j1<j {
v3.push(0.0);
j1=j1+1;
}
res = res + Polynomial::from(v3);
i=i+1;
j=j-1;
}
return res;
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
}
}

Лог от изпълнението

Compiling solution v0.1.0 (file:///tmp/d20171121-6053-c1a731/solution)
warning: unused variable: `points`
  --> src/lib.rs:20:24
   |
20 |     pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
   |                        ^^^^^^
   |
   = note: #[warn(unused_variables)] on by default
   = note: to disable this warning, consider using `_points` instead

warning: unused variable: `points`
  --> src/lib.rs:20:24
   |
20 |     pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
   |                        ^^^^^^
   |
   = note: #[warn(unused_variables)] on by default
   = note: to disable this warning, consider using `_points` instead

    Finished dev [unoptimized + debuginfo] target(s) in 5.52 secs
     Running target/debug/deps/solution-200db9172ea1f728

running 1 test
test tests::it_works ... ok

test result: ok. 1 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 ... FAILED
test solution_test::test_add_poly_zero_one ... FAILED
test solution_test::test_arithmetic_properties ... FAILED
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 ... FAILED
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 ... FAILED
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 ... FAILED

failures:

---- solution_test::test_add_poly stdout ----
	thread 'solution_test::test_add_poly' panicked at 'assertion failed: `(left == right)`
  left: `Polynomial { c: [1, 0] }`,
 right: `Polynomial { c: [2, 1, 2] }`', tests/solution_test.rs:103:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

---- solution_test::test_add_poly_zero_one stdout ----
	thread 'solution_test::test_add_poly_zero_one' panicked at 'assertion failed: `(left == right)`
  left: `Polynomial { c: [0] }`,
 right: `Polynomial { c: [2, 0, 3] }`', tests/solution_test.rs:87:4

---- solution_test::test_arithmetic_properties stdout ----
	thread 'solution_test::test_arithmetic_properties' panicked at 'attempt to subtract with overflow', src/lib.rs:170:8

---- solution_test::test_has_point stdout ----
	thread 'solution_test::test_has_point' panicked at 'attempt to subtract with overflow', src/lib.rs:13:18

---- solution_test::test_lagrange_poly_1 stdout ----
	thread 'solution_test::test_lagrange_poly_1' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:335:20

---- solution_test::test_lagrange_poly_2 stdout ----
	thread 'solution_test::test_lagrange_poly_2' panicked at 'assertion failed: poly.is_some()', tests/solution_test.rs:232:4

---- solution_test::test_mul_poly stdout ----
	thread 'solution_test::test_mul_poly' panicked at 'attempt to subtract with overflow', src/lib.rs:170:8

---- solution_test::test_mul_poly_zero_one stdout ----
	thread 'solution_test::test_mul_poly_zero_one' panicked at 'attempt to subtract with overflow', src/lib.rs:170:8


failures:
    solution_test::test_add_poly
    solution_test::test_add_poly_zero_one
    solution_test::test_arithmetic_properties
    solution_test::test_has_point
    solution_test::test_lagrange_poly_1
    solution_test::test_lagrange_poly_2
    solution_test::test_mul_poly
    solution_test::test_mul_poly_zero_one

test result: FAILED. 7 passed; 8 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--test solution_test'

История (2 версии и 4 коментара)

Биляна качи първо решение на 20.11.2017 14:37 (преди почти 8 години)

Нямаш interpolate, което значи, че решението не ти се компилира! Направи празна имплементация, ако трябва, но ако не ти се компилира кода, получаваш 0 точки. Издължавам срока с час, понеже забравих да проверя домашните по-рано, но ако не прочетеш това навреме, кофти. Написали сме го в инструкциите: https://fmi.rust-lang.bg/tasks/guide.

Издължавам срока до утре, понеже намерих, да кажем, проблем в сайта, който спъва поне един колега. Това не е причината за 0та точки тук, така че приеми, че имаш късмет. Сложи имплементация на interpolate до утре, обаче.

Биляна качи решение на 21.11.2017 15:00 (преди почти 8 години)

#[derive(Debug, Clone)]
pub struct Polynomial {
c : Vec<f64>,
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
let mut i = self.c.len()-1;
let mut acc : f64= 0.0;
for &val in self.c.iter() {
acc = acc + val*power(point.0,i);
i = i -1;
}

Различен начин, по който може би може да напишеш това:

for (i, &val) in self.c.iter().rev().enumerate() {
    acc += val * power(point.0, i)
}

Или нещо в тоя дух, поне. Обръщането на итератора с rev е безплатно, понеже имаме вектор.

if (acc - point.1).abs() < 1e-10 {
return true;
}
return false;
}
-
+ pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
+ None
+ }
+
}
pub fn power(x : f64,i : usize) -> f64 {
if i == 0 {
return 1.0;
}
return x*power(x,i-1);
}

Има вградена функция, която можеш да ползваш за това, която вероятно ще е по-ефективна: https://doc.rust-lang.org/std/primitive.f64.html#method.powi. Само дето трябва да cast-неш аргумента към i32, но не би било проблем за нас, в случая. Доста голям полином трябва да се направи, за да бъде cast-ването проблем :).

impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
if coefs== vec![0.0] || coefs==vec![] {
return Polynomial{ c : vec![0.0] };
}
coefs = coefs.into_iter().skip_while(|&x| x ==0.0).collect();
return Polynomial{c : coefs};
}
}
impl Default for Polynomial {
fn default() -> Self {
Polynomial{ c : vec![0.0] }
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
let mut v1 : Vec<f64> = self.c.clone();
v1=v1.into_iter().skip_while(|&x| x ==0.0).collect();
let mut v2 : Vec<f64> = rhs.c.clone();
v2=v2.into_iter().skip_while(|&y| y== 0.0).collect();
if v1.len() != v2.len() {
return false;
}
let size = v1.len();
let v3 : Vec<f64> = v1.into_iter().zip(v2).map(|(x,y)| (x-y).abs()).filter(|&x| x<1e-10).collect();
if v3.len()!=size {
return false;
}
else {
return true;
}
}
}
use std::ops::Mul;
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
let mut v1 : Vec<f64> = self.c.clone();
v1 = v1.into_iter().map(|x| rhs*x ).collect();
return Polynomial {c : v1};
}
}
use std::ops::Div;
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
let mut v1 : Vec<f64> = self.c.clone();
v1 = v1.into_iter().map(|x| x/rhs ).collect();
return Polynomial {c : v1};
}
}
use std::ops::Add;
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let mut v1 : Vec<f64>=Polynomial::from(self.c.clone()).c;
let size1=v1.len()-1;
let v2 : Vec<f64>=Polynomial::from(rhs.c.clone()).c;
let size2=v2.len()-1;
if size1>size2{
let mut v3: Vec<f64> = vec![];
let mut i:usize =0;
while i<size1-size2{
v3.push(0.0);
i=i+1;
}
for &val in v2.iter() {
v3.push(val);
}
v1=v1.into_iter().zip(v3).map(|(x,y)| x+y).collect();
}
if size1<size2 {
let mut v3: Vec<f64> = vec![];
let mut i:usize =0;
while i<size2-size1{
v3.push(0.0);
i=i+1;
}
for &val in v1.iter() {
v3.push(val);
}
v1=v1.into_iter().zip(v3).map(|(x,y)| x+y).collect();
}
if size1==size2 {
v1=v1.into_iter().zip(v2).map(|(x,y)| x+y).collect();
}
return Polynomial{ c: v1};
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let v1 : Vec<f64>=Polynomial::from(self.c.clone()).c;
let size1=v1.len()-1;
let v2 : Vec<f64>=Polynomial::from(rhs.c.clone()).c;
let size2=v2.len()-1;
let size = size1+size2;
let mut res = Polynomial::from(vec![0.0]);
let mut i : usize = 0;
let mut j = size-size2;
for &val in v1.iter() {
let p1 = Polynomial::from(v2.clone()) * val ;
let mut v3 :Vec<f64> = vec![];
let mut i1 : usize = 0;
while i1<i{
v3.push(0.0);
i1=i1+1;
}
for &v in p1.c.iter() {
v3.push(v);
}
let mut j1: usize =0;
while j1<j {
v3.push(0.0);
j1=j1+1;
}
res = res + Polynomial::from(v3);
i=i+1;
j=j-1;
}
return res;
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
}
}
+