Решение на Polynomial от Недялко Андреев

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

Към профила на Недялко Андреев

Резултати

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

Код

use std::ops::{Add, Div, Mul};
use std::default::Default;
use std::cmp::PartialEq;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>,
}
fn eq(x: f64, y: f64) -> bool {
// TODO: use someting more robust
// https://users.rust-lang.org/t/assert-eq-for-float-numbers/7034/4
(x - y).abs() < 1e-10
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
eq(
point.1,
self.coefs
.iter()
.enumerate()
.fold(0.0, |sum, v| sum + v.1 * f64::powi(point.0, v.0 as i32)),
)
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut res = Polynomial::default();
for (j, jpoint) in points.iter().enumerate() {
let mut interm = Polynomial::new(vec![jpoint.1]);
for (m, mpoint) in points.iter().enumerate() {
if j == m {
continue;
}
if jpoint.0 == mpoint.0 {
return None;
}
interm = interm * Polynomial::new(vec![-mpoint.0, 1.0]) / (jpoint.0 - mpoint.0);
}
res = res + interm;
}
Some(res)
}
fn trim_trailing_zeros(&mut self) {
match self.coefs.iter().rposition(|&x| !eq(x, 0.0)) {
None => self.coefs.clear(),
Some(pos) => self.coefs.truncate(pos + 1),
}
}
fn new(asc_coefs: Vec<f64>) -> Self {
let mut p = Polynomial { coefs: asc_coefs };
p.trim_trailing_zeros();
return p;
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
return Polynomial::new(coefs);
}
}
impl Default for Polynomial {
fn default() -> Polynomial {
Polynomial { coefs: 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() {
if !eq(self.coefs[i], rhs.coefs[i]) {
return false;
}
}
return true;
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
Polynomial::new(self.coefs.iter().map(|&c| c * rhs).collect())
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
Polynomial::new(self.coefs.iter().map(|&c| c / rhs).collect())
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let mut res = vec![0.0; self.coefs.len() + rhs.coefs.len()];
for (li, litem) in self.coefs.iter().enumerate() {
for (ri, ritem) in rhs.coefs.iter().enumerate() {
res[li + ri] = res[li + ri] + litem * ritem
}
}
Polynomial::new(res)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let (mut long, short) = if self.coefs.len() > rhs.coefs.len() {
(self, rhs)
} else {
(rhs, self)
};
for (i, item) in short.coefs.iter().enumerate() {
long.coefs[i] = long.coefs[i] + item;
}
long.trim_trailing_zeros();
long
}
}

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

Compiling solution v0.1.0 (file:///tmp/d20171121-6053-186p0e6/solution)
    Finished dev [unoptimized + debuginfo] target(s) in 5.12 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 ... 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

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests solution

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

История (5 версии и 1 коментар)

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

Недялко качи решение на 20.11.2017 15:06 (преди почти 8 години)

-//use std::ops::{Mul,Div,Add};
+use std::ops::{Mul,Div,Add};
use std::default::Default;
use std::cmp::PartialEq;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>
}
fn eq(x: f64, y: f64) -> bool {
// TODO: use someting more robust
// https://users.rust-lang.org/t/assert-eq-for-float-numbers/7034/4
(x - y).abs() < 1e-10
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
//TODO: do this with iter.fold()?
let mut val = 0.0;
for (i, item) in self.coefs.iter().enumerate() {
val = val + item * f64::powi(point.0, i as i32);
}
eq(val, point.1)
}
/*
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
// TODO
None
}
*/
+
fn trim_trailing_zeros(&mut self) {
match self.coefs.iter().rposition(|&x| ! eq(x, 0.0)) {
None => self.coefs.clear(),
Some(pos) => self.coefs.truncate(pos+1),
}
}
+
+ fn new(asc_coefs: Vec<f64>) -> Self {
+ let mut p = Polynomial{coefs: asc_coefs};
+ p.trim_trailing_zeros();
+ return p
+ }
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
- let mut p = Polynomial{coefs: coefs};
- p.trim_trailing_zeros();
- return p
+ return Polynomial::new(coefs)
}
}
impl Default for Polynomial {
fn default() -> Polynomial {
Polynomial{coefs: 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() {
if ! eq(self.coefs[i], rhs.coefs[i]) {
return false
}
}
return true
}
}
-/*
+
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
- // TODO
- self
+ //TODO: figure out how to do this in-place, without creating a new vector...
+ Polynomial::new(self.coefs.iter().map(|&c| c*rhs).collect())
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
- // TODO
- self
+ //TODO: figure out how to do this in-place, without creating a new vector...
+ Polynomial::new(self.coefs.iter().map(|&c| c/rhs).collect())
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output{
- // TODO
- self
+ let mut res = vec![0.0; self.coefs.len()+rhs.coefs.len()];
+ for (li, litem) in self.coefs.iter().enumerate() {
+ for (ri, ritem) in rhs.coefs.iter().enumerate() {
+ res[li+ri] = res[li+ri] + litem*ritem
+ }
+ }
+ Polynomial::new(res)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output{
- // TODO
- self
+ let (mut long,short) = if self.coefs.len()>rhs.coefs.len() {
+ (self,rhs)
+ } else {
+ (rhs, self)
+ };
+
+ for (i, item) in short.coefs.iter().enumerate() {
+ long.coefs[i] = long.coefs[i] + item;
+ }
+ long.trim_trailing_zeros();
+ long
}
}
-*/

Недялко качи решение на 20.11.2017 15:39 (преди почти 8 години)

use std::ops::{Mul,Div,Add};
use std::default::Default;
use std::cmp::PartialEq;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>
}
fn eq(x: f64, y: f64) -> bool {
// TODO: use someting more robust
// https://users.rust-lang.org/t/assert-eq-for-float-numbers/7034/4
(x - y).abs() < 1e-10
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
//TODO: do this with iter.fold()?
let mut val = 0.0;
for (i, item) in self.coefs.iter().enumerate() {
val = val + item * f64::powi(point.0, i as i32);
}
eq(val, point.1)
}
-/*
+
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
- // TODO
- None
+ let mut res = Polynomial::default();
+
+ for (j, jpoint) in points.iter().enumerate() {
+ let mut interm = Polynomial::new(vec![jpoint.1]);
+ for (m, mpoint) in points.iter().enumerate() {
+ if j == m {
+ continue;
+ }
+ if jpoint.0 == mpoint.0 {
+ return None;
+ }
+ interm = interm
+ * Polynomial::new(vec![-mpoint.0, 1.0])
+ / (jpoint.0 - mpoint.0);
+
+ };
+ res = res + interm;
+ };
+
+ Some(res)
}
-*/
+
fn trim_trailing_zeros(&mut self) {
match self.coefs.iter().rposition(|&x| ! eq(x, 0.0)) {
None => self.coefs.clear(),
Some(pos) => self.coefs.truncate(pos+1),
}
}
fn new(asc_coefs: Vec<f64>) -> Self {
let mut p = Polynomial{coefs: asc_coefs};
p.trim_trailing_zeros();
return p
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
return Polynomial::new(coefs)
}
}
impl Default for Polynomial {
fn default() -> Polynomial {
Polynomial{coefs: 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() {
if ! eq(self.coefs[i], rhs.coefs[i]) {
return false
}
}
return true
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
//TODO: figure out how to do this in-place, without creating a new vector...
Polynomial::new(self.coefs.iter().map(|&c| c*rhs).collect())
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
//TODO: figure out how to do this in-place, without creating a new vector...
Polynomial::new(self.coefs.iter().map(|&c| c/rhs).collect())
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output{
let mut res = vec![0.0; self.coefs.len()+rhs.coefs.len()];
for (li, litem) in self.coefs.iter().enumerate() {
for (ri, ritem) in rhs.coefs.iter().enumerate() {
res[li+ri] = res[li+ri] + litem*ritem
}
}
Polynomial::new(res)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output{
let (mut long,short) = if self.coefs.len()>rhs.coefs.len() {
(self,rhs)
} else {
(rhs, self)
};
for (i, item) in short.coefs.iter().enumerate() {
long.coefs[i] = long.coefs[i] + item;
}
long.trim_trailing_zeros();
long
}
}

Недялко качи решение на 20.11.2017 16:15 (преди почти 8 години)

use std::ops::{Mul,Div,Add};
use std::default::Default;
use std::cmp::PartialEq;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>
}
fn eq(x: f64, y: f64) -> bool {
// TODO: use someting more robust
// https://users.rust-lang.org/t/assert-eq-for-float-numbers/7034/4
(x - y).abs() < 1e-10
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
- //TODO: do this with iter.fold()?
- let mut val = 0.0;
- for (i, item) in self.coefs.iter().enumerate() {
- val = val + item * f64::powi(point.0, i as i32);
- }
- eq(val, point.1)
+ eq(point.1, self.coefs.iter().enumerate().fold(0.0, |sum, v| {
+ sum + v.1 * f64::powi(point.0, v.0 as i32)
+ }))
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut res = Polynomial::default();
for (j, jpoint) in points.iter().enumerate() {
let mut interm = Polynomial::new(vec![jpoint.1]);
for (m, mpoint) in points.iter().enumerate() {
if j == m {
continue;
}
if jpoint.0 == mpoint.0 {
return None;
}
interm = interm
* Polynomial::new(vec![-mpoint.0, 1.0])
/ (jpoint.0 - mpoint.0);
};
res = res + interm;
};
Some(res)
}
fn trim_trailing_zeros(&mut self) {
match self.coefs.iter().rposition(|&x| ! eq(x, 0.0)) {
None => self.coefs.clear(),
Some(pos) => self.coefs.truncate(pos+1),
}
}
fn new(asc_coefs: Vec<f64>) -> Self {
let mut p = Polynomial{coefs: asc_coefs};
p.trim_trailing_zeros();
return p
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
return Polynomial::new(coefs)
}
}
impl Default for Polynomial {
fn default() -> Polynomial {
Polynomial{coefs: 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() {
if ! eq(self.coefs[i], rhs.coefs[i]) {
return false
}
}
return true
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
//TODO: figure out how to do this in-place, without creating a new vector...
Polynomial::new(self.coefs.iter().map(|&c| c*rhs).collect())
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
//TODO: figure out how to do this in-place, without creating a new vector...
Polynomial::new(self.coefs.iter().map(|&c| c/rhs).collect())
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output{
let mut res = vec![0.0; self.coefs.len()+rhs.coefs.len()];
for (li, litem) in self.coefs.iter().enumerate() {
for (ri, ritem) in rhs.coefs.iter().enumerate() {
res[li+ri] = res[li+ri] + litem*ritem
}
}
Polynomial::new(res)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output{
let (mut long,short) = if self.coefs.len()>rhs.coefs.len() {
(self,rhs)
} else {
(rhs, self)
};
for (i, item) in short.coefs.iter().enumerate() {
long.coefs[i] = long.coefs[i] + item;
}
long.trim_trailing_zeros();
long
}
}

Недялко качи решение на 20.11.2017 16:38 (преди почти 8 години)

-use std::ops::{Mul,Div,Add};
+use std::ops::{Add, Div, Mul};
use std::default::Default;
use std::cmp::PartialEq;
#[derive(Debug, Clone)]
pub struct Polynomial {
- coefs: Vec<f64>
+ coefs: Vec<f64>,
}
fn eq(x: f64, y: f64) -> bool {
// TODO: use someting more robust
// https://users.rust-lang.org/t/assert-eq-for-float-numbers/7034/4
(x - y).abs() < 1e-10
}
impl Polynomial {
pub fn has(&self, point: &(f64, f64)) -> bool {
- eq(point.1, self.coefs.iter().enumerate().fold(0.0, |sum, v| {
- sum + v.1 * f64::powi(point.0, v.0 as i32)
- }))
+ eq(
+ point.1,
+ self.coefs
+ .iter()
+ .enumerate()
+ .fold(0.0, |sum, v| sum + v.1 * f64::powi(point.0, v.0 as i32)),
+ )
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut res = Polynomial::default();
for (j, jpoint) in points.iter().enumerate() {
let mut interm = Polynomial::new(vec![jpoint.1]);
for (m, mpoint) in points.iter().enumerate() {
if j == m {
continue;
}
- if jpoint.0 == mpoint.0 {
+ if jpoint.0 == mpoint.0 {
return None;
}
- interm = interm
- * Polynomial::new(vec![-mpoint.0, 1.0])
- / (jpoint.0 - mpoint.0);
-
- };
+ interm = interm * Polynomial::new(vec![-mpoint.0, 1.0]) / (jpoint.0 - mpoint.0);
+ }
res = res + interm;
- };
+ }
Some(res)
}
fn trim_trailing_zeros(&mut self) {
- match self.coefs.iter().rposition(|&x| ! eq(x, 0.0)) {
+ match self.coefs.iter().rposition(|&x| !eq(x, 0.0)) {
None => self.coefs.clear(),
- Some(pos) => self.coefs.truncate(pos+1),
+ Some(pos) => self.coefs.truncate(pos + 1),
}
}
fn new(asc_coefs: Vec<f64>) -> Self {
- let mut p = Polynomial{coefs: asc_coefs};
+ let mut p = Polynomial { coefs: asc_coefs };
p.trim_trailing_zeros();
- return p
+ return p;
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
coefs.reverse();
- return Polynomial::new(coefs)
+ return Polynomial::new(coefs);
}
}
impl Default for Polynomial {
- fn default() -> Polynomial {
- Polynomial{coefs: vec![]}
+ fn default() -> Polynomial {
+ Polynomial { coefs: vec![] }
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
if self.coefs.len() != rhs.coefs.len() {
- return false
+ return false;
}
for i in 0..self.coefs.len() {
- if ! eq(self.coefs[i], rhs.coefs[i]) {
- return false
+ if !eq(self.coefs[i], rhs.coefs[i]) {
+ return false;
}
}
- return true
+ return true;
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
- //TODO: figure out how to do this in-place, without creating a new vector...
- Polynomial::new(self.coefs.iter().map(|&c| c*rhs).collect())
+ Polynomial::new(self.coefs.iter().map(|&c| c * rhs).collect())
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
- //TODO: figure out how to do this in-place, without creating a new vector...
- Polynomial::new(self.coefs.iter().map(|&c| c/rhs).collect())
+ Polynomial::new(self.coefs.iter().map(|&c| c / rhs).collect())
}
}
impl Mul for Polynomial {
type Output = Polynomial;
- fn mul(self, rhs: Polynomial) -> Self::Output{
- let mut res = vec![0.0; self.coefs.len()+rhs.coefs.len()];
+ fn mul(self, rhs: Polynomial) -> Self::Output {
+ let mut res = vec![0.0; self.coefs.len() + rhs.coefs.len()];
for (li, litem) in self.coefs.iter().enumerate() {
for (ri, ritem) in rhs.coefs.iter().enumerate() {
- res[li+ri] = res[li+ri] + litem*ritem
+ res[li + ri] = res[li + ri] + litem * ritem
}
}
Polynomial::new(res)
}
}
impl Add for Polynomial {
type Output = Polynomial;
- fn add(self, rhs: Polynomial) -> Self::Output{
- let (mut long,short) = if self.coefs.len()>rhs.coefs.len() {
- (self,rhs)
+ fn add(self, rhs: Polynomial) -> Self::Output {
+ let (mut long, short) = if self.coefs.len() > rhs.coefs.len() {
+ (self, rhs)
} else {
(rhs, self)
};
for (i, item) in short.coefs.iter().enumerate() {
long.coefs[i] = long.coefs[i] + item;
}
long.trim_trailing_zeros();
long
}
}

Виждам, че сте удължили срока с един ден. Мисля, че това решение съм го докарал до нещо работещо, но не съм сигурен дали съм го написал особено идиоматично. Ако имате време да му хвърлите един поглед, всякакъв feedback е добре дошъл!