Решение на (Floating) Points and Vectors от Димитър Луканов

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

Към профила на Димитър Луканов

Резултати

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

Код

use std::ops::{Add, Sub};
use std::f64::EPSILON as F_EPSILON;
// Clone is so we have the clone() method available for out struct
// Copy is so everytime we attempt to give away ownership we clone() instead
#[derive(Debug, Clone, Copy)]
pub struct Point{
pub x: f64,
pub y: f64,
pub z: f64
}
impl Point {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Self{
x: x,
y: y,
z: z
}
}
}
impl PartialEq for Point {
fn eq(&self, rhs: &Self) -> bool {
((self.x - rhs.x).abs() +
(self.y - rhs.y).abs() +
(self.z - rhs.z).abs())< (3_f64 * F_EPSILON)
}
}
impl Add<Self> for Point {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z
}
}
}
impl Add<Vector> for Point {
type Output = Self;
fn add(self, rhs: Vector) -> Self {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z
}
}
}
impl Sub for Point {
type Output = Vector;
fn sub(self, rhs: Self) -> Vector {
Vector::new(self.x - rhs.x,
self.y - rhs.y,
self.z - rhs.z)
}
}
use std::ops::{Mul, BitXor};
// Clone is so we have the clone() method available for out struct
// Copy is so everytime we attempt to give away ownership we clone() instead
#[derive(Debug, Clone, Copy)]
pub struct Vector{
pub x: f64,
pub y: f64,
pub z: f64
}
impl Vector {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Self{
x: x,
y: y,
z: z
}
}
pub fn is_zero(&self)-> bool {
(self.x == 0_f64) && (self.y == 0_f64) && (self.z == 0_f64)
}
pub fn norm(&self)-> f64 {
((self.x*self.x) +(self.y*self.y) +(self.z*self.z)).sqrt()
}
}
impl PartialEq for Vector {
fn eq(&self, rhs: &Self) -> bool {
((self.x - rhs.x).abs() +
(self.y - rhs.y).abs() +
(self.z - rhs.z).abs())< (3_f64 * F_EPSILON)
}
}
impl Add for Vector {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z
}
}
}
impl Sub for Vector {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z
}
}
}
impl Mul<Vector> for f64{
type Output = Vector;
fn mul(self, rhs: Vector) -> Vector {
Vector{
x: self * rhs.x,
y: self * rhs.y,
z: self * rhs.z
}
}
}
impl Mul<Vector> for Vector{
type Output = f64;
fn mul(self, rhs: Self) -> f64 {
(self.x*rhs.x) + (self.y*rhs.y) + (self.z*rhs.z)
}
}
impl BitXor for Vector {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self{
Self {
x: ((self.y * rhs.z) - (self.z*rhs.y)),
y: ((self.z*rhs.x) - (self.x*rhs.z)),
z: ((self.x*rhs.y) - (self.y*rhs.x))
}
}
}
#[derive(Debug)]
pub struct Line {
start_point: Point,
direction_vector: Vector
}
impl Line{
pub fn from_pv(start: Point, direction_vector: Vector) -> Option<Self>{
if direction_vector.is_zero() {
None
}
else {
Some(
Self {
start_point: start,
direction_vector: direction_vector
}
)
}
}
pub fn from_pp(start: Point, end: Point) -> Option<Self>{
let direction_vector: Vector = end - start;
Line::from_pv(start, direction_vector)
}
pub fn distance(&self, point: Point) -> f64 {
// this will be the vector from the start point of the line
// to the given point.
// (FromStartToPoint)
let vec_fstp: Vector = point - self.start_point;
let cross_prod: Vector = vec_fstp ^ self.direction_vector;
cross_prod.norm() / self.direction_vector.norm()
}
}
impl PartialEq for Line {
fn eq(&self, other: &Self) -> bool {
(other.distance(self.start_point) == 0_f64) && (other.distance(self.start_point + self.direction_vector) == 0_f64)
}
}

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

Compiling solution v0.1.0 (/tmp/d20190123-22631-1r0qm50/solution)
    Finished dev [unoptimized + debuginfo] target(s) in 4.10s
     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 ... FAILED
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

failures:

---- solution_test::test_line_equality_by_vectors stdout ----
thread 'solution_test::test_line_equality_by_vectors' panicked at 'assertion failed: `(left == right)`
  left: `Some(Line { start_point: Point { x: 0.0, y: 0.4, z: 0.0 }, direction_vector: Vector { x: 0.1, y: -0.2, z: 0.5 } })`,
 right: `Some(Line { start_point: Point { x: 0.0000000000000000002220446049250313, y: 0.4, z: 0.0000000000000000002220446049250313 }, direction_vector: Vector { x: 0.1, y: -0.2, z: 0.5 } })`', tests/solution_test.rs:230:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    solution_test::test_line_equality_by_vectors

test result: FAILED. 14 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

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

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

Димитър качи първо решение на 25.11.2018 15:26 (преди почти 5 години)

Премахни pub mod point, pub mod vector и pub mod line. Дефинирани по този начин, името се получава solution::point::Point, а ние го адресираме в тестовете като solution::Point. Тестовете съответно не се компилират.

Що се отнася до индентацията, подозирам, че си мешил табове и интервали. Настрой си табовете в редактора да са 8 символа широки, и вероятно ще видиш подобна картинка.

Димитър качи решение на 25.11.2018 21:45 (преди почти 5 години)

-pub mod point {
+use std::ops::{Add, Sub};
+use std::f64::EPSILON as F_EPSILON;
- use std::ops::{Add, Sub};
- use vector::Vector;
+// Clone is so we have the clone() method available for out struct
+// Copy is so everytime we attempt to give away ownership we clone() instead
+#[derive(Debug, Clone, Copy)]
+pub struct Point{
+ pub x: f64,
+ pub y: f64,
+ pub z: f64
+}
- use std::f64::EPSILON as F_EPSILON;
+impl Point {
- // Clone is so we have the clone() method available for out struct
- // Copy is so everytime we attempt to give away ownership we clone() instead
- #[derive(Debug, Clone, Copy)]
- pub struct Point{
- pub x: f64,
- pub y: f64,
- pub z: f64
- }
+ pub fn new(x: f64, y: f64, z: f64) -> Self {
+ Self{
+ x: x,
+ y: y,
+ z: z
+ }
+ }
+}
- impl Point {
+impl PartialEq for Point {
+ fn eq(&self, rhs: &Self) -> bool {
+ ((self.x - rhs.x).abs() +
+ (self.y - rhs.y).abs() +
+ (self.z - rhs.z).abs())< (3_f64 * F_EPSILON)
+ }
+}
- pub fn new(x: f64, y: f64, z: f64) -> Self {
- Self{
- x: x,
- y: y,
- z: z
- }
- }
- }
+impl Add<Self> for Point {
+ type Output = Self;
- impl PartialEq for Point {
- fn eq(&self, rhs: &Self) -> bool {
- ((self.x - rhs.x).abs() +
- (self.y - rhs.y).abs() +
- (self.z - rhs.z).abs())< (3_f64 * F_EPSILON)
- }
- }
-
- impl Add<Self> for Point {
- type Output = Self;
-
- fn add(self, rhs: Self) -> Self {
- Self {
- x: self.x + rhs.x,
- y: self.y + rhs.y,
- z: self.z + rhs.z
- }
- }
+ fn add(self, rhs: Self) -> Self {
+ Self {
+ x: self.x + rhs.x,
+ y: self.y + rhs.y,
+ z: self.z + rhs.z
+ }
}
+}
- impl Add<Vector> for Point {
- type Output = Self;
+impl Add<Vector> for Point {
+ type Output = Self;
- fn add(self, rhs: Vector) -> Self {
- Self {
- x: self.x + rhs.x,
- y: self.y + rhs.y,
- z: self.z + rhs.z
- }
- }
+ fn add(self, rhs: Vector) -> Self {
+ Self {
+ x: self.x + rhs.x,
+ y: self.y + rhs.y,
+ z: self.z + rhs.z
+ }
}
+}
- impl Sub for Point {
- type Output = Vector;
+impl Sub for Point {
+ type Output = Vector;
- fn sub(self, rhs: Self) -> Vector {
- Vector::new(self.x - rhs.x,
- self.y - rhs.y,
- self.z - rhs.z)
- }
+ fn sub(self, rhs: Self) -> Vector {
+ Vector::new(self.x - rhs.x,
+ self.y - rhs.y,
+ self.z - rhs.z)
}
}
-pub mod vector{
+use std::ops::{Mul, BitXor};
+// Clone is so we have the clone() method available for out struct
+// Copy is so everytime we attempt to give away ownership we clone() instead
+#[derive(Debug, Clone, Copy)]
+pub struct Vector{
+ pub x: f64,
+ pub y: f64,
+ pub z: f64
+}
- use std::ops::{Add, Sub, Mul, BitXor};
- use std::f64::EPSILON as F_EPSILON;
+impl Vector {
- // Clone is so we have the clone() method available for out struct
- // Copy is so everytime we attempt to give away ownership we clone() instead
- #[derive(Debug, Clone, Copy)]
- pub struct Vector{
- pub x: f64,
- pub y: f64,
- pub z: f64
+ pub fn new(x: f64, y: f64, z: f64) -> Self {
+ Self{
+ x: x,
+ y: y,
+ z: z
+ }
}
- impl Vector {
-
- pub fn new(x: f64, y: f64, z: f64) -> Self {
- Self{
- x: x,
- y: y,
- z: z
- }
- }
-
- pub fn is_zero(&self)-> bool {
- (self.x == 0_f64) && (self.y == 0_f64) && (self.z == 0_f64)
- }
-
- pub fn norm(&self)-> f64 {
- ((self.x*self.x) +(self.y*self.y) +(self.z*self.z)).sqrt()
- }
+ pub fn is_zero(&self)-> bool {
+ (self.x == 0_f64) && (self.y == 0_f64) && (self.z == 0_f64)
}
- impl PartialEq for Vector {
- fn eq(&self, rhs: &Self) -> bool {
- ((self.x - rhs.x).abs() +
- (self.y - rhs.y).abs() +
- (self.z - rhs.z).abs())< (3_f64 * F_EPSILON)
- }
+ pub fn norm(&self)-> f64 {
+ ((self.x*self.x) +(self.y*self.y) +(self.z*self.z)).sqrt()
}
+}
- impl Add for Vector {
- type Output = Self;
+impl PartialEq for Vector {
+ fn eq(&self, rhs: &Self) -> bool {
+ ((self.x - rhs.x).abs() +
+ (self.y - rhs.y).abs() +
+ (self.z - rhs.z).abs())< (3_f64 * F_EPSILON)
+ }
+}
- fn add(self, rhs: Self) -> Self {
- Self {
- x: self.x + rhs.x,
- y: self.y + rhs.y,
- z: self.z + rhs.z
- }
+impl Add for Vector {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ Self {
+ x: self.x + rhs.x,
+ y: self.y + rhs.y,
+ z: self.z + rhs.z
}
}
+}
- impl Sub for Vector {
- type Output = Self;
+impl Sub for Vector {
+ type Output = Self;
- fn sub(self, rhs: Self) -> Self {
- Self {
- x: self.x - rhs.x,
- y: self.y - rhs.y,
- z: self.z - rhs.z
- }
+ fn sub(self, rhs: Self) -> Self {
+ Self {
+ x: self.x - rhs.x,
+ y: self.y - rhs.y,
+ z: self.z - rhs.z
}
}
+}
- impl Mul<Vector> for f64{
- type Output = Vector;
+impl Mul<Vector> for f64{
+ type Output = Vector;
- fn mul(self, rhs: Vector) -> Vector {
- Vector{
- x: self * rhs.x,
- y: self * rhs.y,
- z: self * rhs.z
- }
+ fn mul(self, rhs: Vector) -> Vector {
+ Vector{
+ x: self * rhs.x,
+ y: self * rhs.y,
+ z: self * rhs.z
}
}
+}
- impl Mul<Vector> for Vector{
- type Output = f64;
+impl Mul<Vector> for Vector{
+ type Output = f64;
- fn mul(self, rhs: Self) -> f64 {
- (self.x*rhs.x) + (self.y*rhs.y) + (self.z*rhs.z)
- }
- }
+ fn mul(self, rhs: Self) -> f64 {
+ (self.x*rhs.x) + (self.y*rhs.y) + (self.z*rhs.z)
+ }
+}
- impl BitXor for Vector {
- type Output = Self;
+impl BitXor for Vector {
+ type Output = Self;
- fn bitxor(self, rhs: Self) -> Self{
- Self {
- x: ((self.y * rhs.z) - (self.z*rhs.y)),
- y: ((self.z*rhs.x) - (self.x*rhs.z)),
- z: ((self.x*rhs.y) - (self.y*rhs.x))
- }
+ fn bitxor(self, rhs: Self) -> Self{
+ Self {
+ x: ((self.y * rhs.z) - (self.z*rhs.y)),
+ y: ((self.z*rhs.x) - (self.x*rhs.z)),
+ z: ((self.x*rhs.y) - (self.y*rhs.x))
}
}
}
-pub mod line{
+#[derive(Debug)]
+pub struct Line {
+ start_point: Point,
+ direction_vector: Vector
+}
- use point::Point;
- use vector::Vector;
+impl Line{
- #[derive(Debug)]
- pub struct Line {
- start_point: Point,
- direction_vector: Vector
+ pub fn from_pv(start: Point, direction_vector: Vector) -> Option<Self>{
+ if direction_vector.is_zero() {
+ None
+ }
+ else {
+ Some(
+ Self {
+ start_point: start,
+ direction_vector: direction_vector
+ }
+ )
+ }
}
- impl Line{
+ pub fn from_pp(start: Point, end: Point) -> Option<Self>{
+ let direction_vector: Vector = end - start;
+
+ Line::from_pv(start, direction_vector)
+ }
- pub fn from_pv(start: Point, direction_vector: Vector) -> Option<Self>{
- if direction_vector.is_zero() {
- None
- }
- else {
- Some(
- Self {
- start_point: start,
- direction_vector: direction_vector
- }
- )
- }
- }
-
- pub fn from_pp(start: Point, end: Point) -> Option<Self>{
- let direction_vector :Vector = end - start;
-
- Line::from_pv(start, direction_vector)
- }
-
- pub fn distance(&self, point: Point) -> f64 {
- // this will be the vector from the start point of the line
- // to the given point.
- // (FromStartToPoint)
- let vec_fstp :Vector = point - self.start_point;
- let cross_prod :Vector = vec_fstp ^ self.direction_vector;
- cross_prod.norm() / self.direction_vector.norm()
- }
+ pub fn distance(&self, point: Point) -> f64 {
+ // this will be the vector from the start point of the line
+ // to the given point.
+ // (FromStartToPoint)
+ let vec_fstp: Vector = point - self.start_point;
+ let cross_prod: Vector = vec_fstp ^ self.direction_vector;
+ cross_prod.norm() / self.direction_vector.norm()
}
+}
- impl PartialEq for Line {
- fn eq(&self, other: &Self) -> bool {
- (other.distance(self.start_point) == 0_f64) && (other.distance(self.start_point + self.direction_vector) == 0_f64)
- }
+impl PartialEq for Line {
+ fn eq(&self, other: &Self) -> bool {
+ (other.distance(self.start_point) == 0_f64) && (other.distance(self.start_point + self.direction_vector) == 0_f64)
}
}
+
+#[test]
+fn test_basic() {
+ let v1 = Vector::new(1.0, 1.0, 1.0);
+ let v2 = Vector::new(2.0, 2.0, 2.0);
+
+ let p1 = Point::new(1.0, 1.0, 1.0);
+ let p2 = Point::new(2.0, 2.0, 2.0);
+
+ assert!(v1 == v1);
+ assert!(p1 == p1);
+ assert!(v1 != v2);
+ assert!(p1 != p2);
+
+ assert_eq!(p1 + v1, p2);
+ assert_eq!(p2 - p1, v1);
+ assert_eq!(v1 + v1, v2);
+ assert_eq!(2.0 * v1, v2);
+ assert_eq!(v1 * v2, 6.0);
+ assert_eq!(v1 ^ v2, Vector::new(0.0, 0.0, 0.0));
+
+ assert_eq!(
+ Line::from_pv(Point::new(0.0, 0.0, 0.0), Vector::new(1.0, 1.0, 1.0)).unwrap().distance(p1),
+ 0_f64
+ );
+ assert_eq!(
+ Line::from_pv(Point::new(0.0, 0.0, 0.0), Vector::new(1.0, 1.0, 1.0)),
+ Line::from_pv(Point::new(0.0, 0.0, 0.0), Vector::new(2.0, 2.0, 2.0))
+ );
+}

Димитър качи решение на 25.11.2018 21:46 (преди почти 5 години)

use std::ops::{Add, Sub};
use std::f64::EPSILON as F_EPSILON;
// Clone is so we have the clone() method available for out struct
// Copy is so everytime we attempt to give away ownership we clone() instead
#[derive(Debug, Clone, Copy)]
pub struct Point{
pub x: f64,
pub y: f64,
pub z: f64
}
impl Point {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Self{
x: x,
y: y,
z: z
}
}
}
impl PartialEq for Point {
fn eq(&self, rhs: &Self) -> bool {
((self.x - rhs.x).abs() +
(self.y - rhs.y).abs() +
(self.z - rhs.z).abs())< (3_f64 * F_EPSILON)
}
}
impl Add<Self> for Point {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z
}
}
}
impl Add<Vector> for Point {
type Output = Self;
fn add(self, rhs: Vector) -> Self {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z
}
}
}
impl Sub for Point {
type Output = Vector;
fn sub(self, rhs: Self) -> Vector {
Vector::new(self.x - rhs.x,
self.y - rhs.y,
self.z - rhs.z)
}
}
use std::ops::{Mul, BitXor};
// Clone is so we have the clone() method available for out struct
// Copy is so everytime we attempt to give away ownership we clone() instead
#[derive(Debug, Clone, Copy)]
pub struct Vector{
pub x: f64,
pub y: f64,
pub z: f64
}
impl Vector {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Self{
x: x,
y: y,
z: z
}
}
pub fn is_zero(&self)-> bool {
(self.x == 0_f64) && (self.y == 0_f64) && (self.z == 0_f64)
}
pub fn norm(&self)-> f64 {
((self.x*self.x) +(self.y*self.y) +(self.z*self.z)).sqrt()
}
}
impl PartialEq for Vector {
fn eq(&self, rhs: &Self) -> bool {
((self.x - rhs.x).abs() +
(self.y - rhs.y).abs() +
(self.z - rhs.z).abs())< (3_f64 * F_EPSILON)
}
}
impl Add for Vector {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z
}
}
}
impl Sub for Vector {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z
}
}
}
impl Mul<Vector> for f64{
type Output = Vector;
fn mul(self, rhs: Vector) -> Vector {
Vector{
x: self * rhs.x,
y: self * rhs.y,
z: self * rhs.z
}
}
}
impl Mul<Vector> for Vector{
type Output = f64;
fn mul(self, rhs: Self) -> f64 {
(self.x*rhs.x) + (self.y*rhs.y) + (self.z*rhs.z)
}
}
impl BitXor for Vector {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self{
Self {
x: ((self.y * rhs.z) - (self.z*rhs.y)),
y: ((self.z*rhs.x) - (self.x*rhs.z)),
z: ((self.x*rhs.y) - (self.y*rhs.x))
}
}
}
#[derive(Debug)]
pub struct Line {
start_point: Point,
direction_vector: Vector
}
impl Line{
pub fn from_pv(start: Point, direction_vector: Vector) -> Option<Self>{
if direction_vector.is_zero() {
None
}
else {
Some(
Self {
start_point: start,
direction_vector: direction_vector
}
)
}
}
pub fn from_pp(start: Point, end: Point) -> Option<Self>{
let direction_vector: Vector = end - start;
Line::from_pv(start, direction_vector)
}
pub fn distance(&self, point: Point) -> f64 {
// this will be the vector from the start point of the line
// to the given point.
// (FromStartToPoint)
let vec_fstp: Vector = point - self.start_point;
let cross_prod: Vector = vec_fstp ^ self.direction_vector;
cross_prod.norm() / self.direction_vector.norm()
}
}
impl PartialEq for Line {
fn eq(&self, other: &Self) -> bool {
(other.distance(self.start_point) == 0_f64) && (other.distance(self.start_point + self.direction_vector) == 0_f64)
}
-}
-
-#[test]
-fn test_basic() {
- let v1 = Vector::new(1.0, 1.0, 1.0);
- let v2 = Vector::new(2.0, 2.0, 2.0);
-
- let p1 = Point::new(1.0, 1.0, 1.0);
- let p2 = Point::new(2.0, 2.0, 2.0);
-
- assert!(v1 == v1);
- assert!(p1 == p1);
- assert!(v1 != v2);
- assert!(p1 != p2);
-
- assert_eq!(p1 + v1, p2);
- assert_eq!(p2 - p1, v1);
- assert_eq!(v1 + v1, v2);
- assert_eq!(2.0 * v1, v2);
- assert_eq!(v1 * v2, 6.0);
- assert_eq!(v1 ^ v2, Vector::new(0.0, 0.0, 0.0));
-
- assert_eq!(
- Line::from_pv(Point::new(0.0, 0.0, 0.0), Vector::new(1.0, 1.0, 1.0)).unwrap().distance(p1),
- 0_f64
- );
- assert_eq!(
- Line::from_pv(Point::new(0.0, 0.0, 0.0), Vector::new(1.0, 1.0, 1.0)),
- Line::from_pv(Point::new(0.0, 0.0, 0.0), Vector::new(2.0, 2.0, 2.0))
- );
}

Разумно решение, но има две места, на които си сравнил директно с нула, вместо пак да приложиш "достатъчно близко" сравнение. В is_zero метода (който не би трябвало да е проблем), и когато сравняваш прави, двете разстояния са проверени за == 0.0. Мисля, че затова ти липсва точка, съдейки по тестовете.