Решение на 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 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 е добре дошъл!