Решение на (Floating) Points and Vectors от Мария Божкова

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

Към профила на Мария Божкова

Резултати

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

Код

use std::ops::{Add, Sub, Mul, BitXor};
fn float_eq(first: f64, second: f64) -> bool {
(first - second).abs() < std::f64::EPSILON
}
#[derive(Debug, Clone, Copy)]
// Without Copy, we would have problems with moved values
pub struct Point {
x: f64,
y: f64,
z: f64,
}
impl Point {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Point {x, y, z}
}
}
impl Add<Vector> for Point {
type Output = Point;
fn add(self, vec: Vector) -> Point {
Point::new(self.x + vec.x, self.y + vec.y, self.z + vec.z)
}
}
impl Sub for Point {
type Output = Vector;
fn sub(self, other: Point) -> Vector {
Vector::new(self.x - other.x, self.y - other.y, self.z - other.z)
}
}
impl PartialEq for Point {
fn eq(&self, other: &Point) -> bool {
float_eq(self.x, other.x) && float_eq(self.y, other.y) && float_eq(self.z, other.z)
}
fn ne(&self, other: &Point) -> bool {
!float_eq(self.x, other.x) || !float_eq(self.y, other.y) || !float_eq(self.z, other.z)
}

Няма нужда да имплементираш ne метода на PartialEq -- имплементира се автоматично. В документацията на trait-ове, може да видиш че се разделят на "Required methods" и "Provided methods".

}
#[derive(Debug, Clone, Copy)]
pub struct Vector {
x: f64,
y: f64,
z: f64,
}
impl Vector {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Vector{x, y, z}
}
fn dist(&self) -> f64 {
f64::sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
}
fn normalise(&self) -> Vector {
let dist = self.dist();
Vector::new(self.x/dist, self.y/dist, self.z/dist)
}
}
impl Add for Vector {
type Output = Vector;
fn add(self, vec: Vector) -> Vector {
Vector::new(self.x + vec.x, self.y + vec.y, self.z + vec.z)
}
}
impl Mul<Vector> for f64 {
type Output = Vector;
fn mul(self, vec: Vector) -> Vector {
Vector::new(vec.x * self, vec.y * self, vec.z * self)
}
}
impl Mul<Vector> for Vector {
type Output = f64;
fn mul(self, other: Vector) -> f64 {
self.x * other.x + self.y * other.y + self.z * other.z
}
}
impl BitXor for Vector {
type Output = Vector;
fn bitxor(self, other: Vector) -> Vector {
let x = self.y * other.z - self.z * other.y;
let y = self.z * other.x - self.x * other.z;
let z = self.x * other.y - self.y * other.x;
Vector::new(x, y, z)
}
}
impl PartialEq for Vector {
fn eq(&self, other: &Vector) -> bool {
float_eq(self.x, other.x) && float_eq(self.y, other.y) && float_eq(self.z, other.z)
}
fn ne(&self, other: &Vector) -> bool {
!float_eq(self.x, other.x) || !float_eq(self.y, other.y) || !float_eq(self.z, other.z)
}
}
#[derive(Debug)]
pub struct Line {
first_point: Point,
second_point: Point,
}
impl Line {
pub fn from_pp(p1: Point, p2: Point) -> Option<Self> {
if p1 == p2 {
return None;
}
Some(Line {
first_point: p1,
second_point: p2,
})
}
pub fn from_pv(p: Point, v: Vector) -> Option<Self> {
if v == Vector::new(0.0, 0.0, 0.0) {
return None;
}
Some(Line {
first_point: p,
second_point: p + v,
})
}
pub fn distance(&self, target: Point) -> f64 {
let vec = target - self.first_point;
let u_vec = (self.first_point - self.second_point).normalise();
(vec ^ u_vec).dist()/(u_vec).dist()
}
}
impl PartialEq for Line {
fn eq(&self, other: &Line) -> bool {
float_eq(self.distance(other.first_point), 0.0) && float_eq(self.distance(other.second_point), 0.0)
}
fn ne(&self, other: &Line) -> bool {
!float_eq(self.distance(other.first_point), 0.0) || !float_eq(self.distance(other.second_point), 0.0)
}
}

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

Compiling solution v0.1.0 (/tmp/d20190123-22631-did8p1/solution)
    Finished dev [unoptimized + debuginfo] target(s) in 5.06s
     Running target/debug/deps/solution-2e785d603b538f71

running 0 tests

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

     Running target/debug/deps/solution_test-29808948fb50ed3a

running 15 tests
test solution_test::test_equailty_symmetry ... ok
test solution_test::test_equality_basic ... ok
test solution_test::test_equality_floating ... ok
test solution_test::test_line_constructors ... ok
test solution_test::test_line_equality_by_points ... ok
test solution_test::test_line_equality_by_points_and_vectors ... ok
test solution_test::test_line_equality_by_vectors ... ok
test solution_test::test_line_validity ... ok
test solution_test::test_number_by_vector ... ok
test solution_test::test_number_vector_multiplication_with_precision ... ok
test solution_test::test_point_distance ... ok
test solution_test::test_points_minus_points ... ok
test solution_test::test_points_plus_vectors ... ok
test solution_test::test_vector_by_vector ... ok
test solution_test::test_vector_by_vector_cross ... 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

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

Мария качи първо решение на 26.11.2018 02:04 (преди почти 3 години)

Мария качи решение на 26.11.2018 09:03 (преди почти 3 години)

use std::ops::{Add, Sub, Mul, BitXor};
-// impl PartialEq for f64 {
-// fn eq(&self, other: f64) -> bool {
-// (self - other).abs() < std::f64::EPSILON
-// }
-// }
-
fn float_eq(first: f64, second: f64) -> bool {
(first - second).abs() < std::f64::EPSILON
}
#[derive(Debug, Clone, Copy)]
// Without Copy, we would have problems with moved values
pub struct Point {
x: f64,
y: f64,
z: f64,
}
impl Point {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Point {x, y, z}
}
}
impl Add<Vector> for Point {
type Output = Point;
fn add(self, vec: Vector) -> Point {
Point::new(self.x + vec.x, self.y + vec.y, self.z + vec.z)
}
}
impl Sub for Point {
type Output = Vector;
fn sub(self, other: Point) -> Vector {
Vector::new(self.x - other.x, self.y - other.y, self.z - other.z)
}
}
impl PartialEq for Point {
fn eq(&self, other: &Point) -> bool {
- // self.x == other.x && self.y == other.y && self.z == other.z
float_eq(self.x, other.x) && float_eq(self.y, other.y) && float_eq(self.z, other.z)
}
fn ne(&self, other: &Point) -> bool {
- // self.x != other.x || self.y != other.y || self.z != other.z
!float_eq(self.x, other.x) || !float_eq(self.y, other.y) || !float_eq(self.z, other.z)
}

Няма нужда да имплементираш ne метода на PartialEq -- имплементира се автоматично. В документацията на trait-ове, може да видиш че се разделят на "Required methods" и "Provided methods".

}
#[derive(Debug, Clone, Copy)]
pub struct Vector {
x: f64,
y: f64,
z: f64,
}
impl Vector {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Vector{x, y, z}
}
fn dist(&self) -> f64 {
f64::sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
}
fn normalise(&self) -> Vector {
let dist = self.dist();
Vector::new(self.x/dist, self.y/dist, self.z/dist)
}
}
impl Add for Vector {
type Output = Vector;
fn add(self, vec: Vector) -> Vector {
Vector::new(self.x + vec.x, self.y + vec.y, self.z + vec.z)
}
}
impl Mul<Vector> for f64 {
type Output = Vector;
fn mul(self, vec: Vector) -> Vector {
Vector::new(vec.x * self, vec.y * self, vec.z * self)
}
}
impl Mul<Vector> for Vector {
type Output = f64;
fn mul(self, other: Vector) -> f64 {
self.x * other.x + self.y * other.y + self.z * other.z
}
}
impl BitXor for Vector {
type Output = Vector;
fn bitxor(self, other: Vector) -> Vector {
let x = self.y * other.z - self.z * other.y;
let y = self.z * other.x - self.x * other.z;
let z = self.x * other.y - self.y * other.x;
Vector::new(x, y, z)
}
}
impl PartialEq for Vector {
fn eq(&self, other: &Vector) -> bool {
float_eq(self.x, other.x) && float_eq(self.y, other.y) && float_eq(self.z, other.z)
}
fn ne(&self, other: &Vector) -> bool {
!float_eq(self.x, other.x) || !float_eq(self.y, other.y) || !float_eq(self.z, other.z)
}
}
#[derive(Debug)]
pub struct Line {
first_point: Point,
second_point: Point,
}
impl Line {
pub fn from_pp(p1: Point, p2: Point) -> Option<Self> {
if p1 == p2 {
return None;
}
Some(Line {
first_point: p1,
second_point: p2,
})
}
pub fn from_pv(p: Point, v: Vector) -> Option<Self> {
if v == Vector::new(0.0, 0.0, 0.0) {
return None;
}
Some(Line {
first_point: p,
second_point: p + v,
})
}
pub fn distance(&self, target: Point) -> f64 {
let vec = target - self.first_point;
let u_vec = (self.first_point - self.second_point).normalise();
(vec ^ u_vec).dist()/(u_vec).dist()
}
}
impl PartialEq for Line {
fn eq(&self, other: &Line) -> bool {
float_eq(self.distance(other.first_point), 0.0) && float_eq(self.distance(other.second_point), 0.0)
}
fn ne(&self, other: &Line) -> bool {
!float_eq(self.distance(other.first_point), 0.0) || !float_eq(self.distance(other.second_point), 0.0)
}
}