Решение на (Floating) Points and Vectors от Димитър Михайлов

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

Към профила на Димитър Михайлов

Резултати

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

Код

use std::ops::{Add, Sub, Mul, BitXor };
#[derive(Debug, Clone, Copy)]
pub struct Point {
x: f64,
y: f64,
z: f64
}
impl Point {
pub fn new(_x: f64, _y: f64, _z: f64) -> Self {
return Point{x: _x, y: _y, z: _z};
}

Име, което започва с _ обикновено се използва за променлива, която не се използва. Още, ако бяха x, y, z, щеше да можеш да напишеш доста краткото Point { x, y, z } -- ако имената на локалните променливи са същите като ключовете, може да се съкрати foo: foo на просто foo.

}
impl PartialEq for Point {
fn eq(&self, other: &Point) -> bool {
self.x == other.x && self.y == other.y && self.z == other.z

Част от тестовете вероятно fail-ват заради това сравнение. Част от задачата беше да сравнявате floating-point числа с определена точност, вместо с директно сравнение. Погледни някое от другите домашни за това как би станало правилно (за нашите цели) решение.

Може и да разгледаш approx пакета за по-подробно описание на проблема и възможните му решения.

}
}
impl Eq for Point {}
impl Add<Vector> for Point {
type Output = Point;
fn add(self, other: Vector) -> Point {
Point{x: self.x + other.x, y: self.y + other.y, z: self.z + other.z}
}
}
impl Sub for Point {
type Output = Vector;
fn sub(self, other: Point) -> Vector {
Vector{x: self.x - other.x, y: self.y - other.y, z: self.z - other.z}
}
}
#[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 {
return Vector{x: x, y: y, z: z};
}
}
impl PartialEq for Vector {
fn eq(&self, other: &Vector) -> bool {
self.x == other.x && self.y == other.y && self.z == other.z
}
}
impl Eq for Vector {}
impl Add for Vector {
type Output = Vector;
fn add(self, other: Vector) -> Vector {
Vector{x: self.x + other.x, y: self.y + other.y, z: self.z + other.z}
}
}
impl Mul<Vector> for f64 {
type Output = Vector;
fn mul(self, other: Vector) -> Vector {
Vector{x: other.x * self, y: other.y * self, z: other.z * self}
}
}
impl Mul 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 {
Vector{x: self.y * other.z - self.z * other.y, y: self.z * other.x - self.x * other.z, z: self.x * other.y - self.y * other.x}
}
}
#[derive(Debug)]
pub struct Line {
point: Point,
vector: Vector
}
impl Line {
pub fn from_pp(p1: Point, p2: Point) -> Option<Self> {
if p1 == p2 {
None
}
else {
let v = p2-p1;
Some(Line{point: p1, vector: v})
}
}
pub fn from_pv(p: Point, v: Vector) -> Option<Self> {
if v == Vector::new(0.0, 0.0, 0.0) {
None
}
else {
Some(Line{point: p, vector: v})
}
}
pub fn distance(&self, target: Point) -> f64 {
let v = self.point - target;
let norm = (self.vector.x.powf(2.0) + self.vector.y.powf(2.0) + self.vector.z.powf(2.0)).sqrt();
(v * self.vector) / norm
}
}
impl PartialEq for Line {
fn eq(&self, other: &Line) -> bool{
if self.point != other.point {
return false
}
else {
if (self.point == other.point) &&
(self.vector.x / other.vector.x == self.vector.y / other.vector.y) && (self.vector.y / other.vector.y == self.vector.z / other.vector.z) {
return true
}
}
return false
}

Това не ми изглежда правилно, но не съм задълбавал в логиката. Първото условие обаче със сигурност ще е проблем -- Напълно е възможно началото на една права и това на друга права да са различни точки, но да са една и съща права. Примерно:

Line.from_pv(Point::new(0.0, 0.0, 0.0), Vector::new(1.0, 1.0, 1.0))
Line.from_pv(Point::new(1.0, 1.0, 1.0), Vector::new(-1.0, -1.0, -1.0))

Това са една и съща права. Едната започва от нулевата точка и има още една точка в (1, 1, 1). Другата започва от (1, 1, 1) и има вектор, който сочи наобратно -- което я прави идентична с първата. Твоето сравнение на self.point != other.point директно би върнало false.

}
fn main() {
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)),
Line::from_pv(Point::new(0.0, 0.0, 0.0), Vector::new(2.0, 2.0, 2.0)));
}

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

Compiling solution v0.1.0 (/tmp/d20190123-22631-1q3dcd9/solution)
warning: function is never used: `main`
   --> src/lib.rs:146:1
    |
146 | fn main() {
    | ^^^^^^^^^
    |
    = note: #[warn(dead_code)] on by default

    Finished dev [unoptimized + debuginfo] target(s) in 5.19s
     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 ... FAILED
test solution_test::test_equality_basic ... ok
test solution_test::test_equality_floating ... FAILED
test solution_test::test_line_constructors ... ok
test solution_test::test_line_equality_by_points ... FAILED
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 ... FAILED
test solution_test::test_point_distance ... FAILED
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_equailty_symmetry stdout ----
thread 'solution_test::test_equailty_symmetry' panicked at 'assertion failed: `(left == right)`
  left: `Point { x: 0.0, y: 0.0, z: 0.0 }`,
 right: `Point { x: 0.0000000000000000002220446049250313, y: 0.0, z: 0.0 }`', tests/solution_test.rs:63:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

---- solution_test::test_equality_floating stdout ----
thread 'solution_test::test_equality_floating' panicked at 'assertion failed: `(left == right)`
  left: `Point { x: 0.30000000000000004, y: 0.0, z: 0.0 }`,
 right: `Point { x: 0.3, y: 0.0, z: 0.0 }`', tests/solution_test.rs:40:5

---- solution_test::test_line_equality_by_points stdout ----
thread 'solution_test::test_line_equality_by_points' panicked at 'assertion failed: `(left == right)`
  left: `Some(Line { point: Point { x: 0.0, y: 0.0, z: 0.0 }, vector: Vector { x: 0.1, y: 0.1, z: 0.1 } })`,
 right: `Some(Line { point: Point { x: 0.1, y: 0.1, z: 0.1 }, vector: Vector { x: -0.1, y: -0.1, z: -0.1 } })`', tests/solution_test.rs:206:5

---- 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 { point: Point { x: 0.0, y: 0.4, z: 0.0 }, vector: Vector { x: 0.1, y: -0.2, z: 0.5 } })`,
 right: `Some(Line { point: Point { x: 0.0000000000000000002220446049250313, y: 0.4, z: 0.0000000000000000002220446049250313 }, vector: Vector { x: 0.1, y: -0.2, z: 0.5 } })`', tests/solution_test.rs:230:5

---- solution_test::test_number_vector_multiplication_with_precision stdout ----
thread 'solution_test::test_number_vector_multiplication_with_precision' panicked at 'assertion failed: `(left == right)`
  left: `Vector { x: 0.0000000000000000002220446049250313, y: 0.0000000000000000002220446049250313, z: 0.0000000000000000002220446049250313 }`,
 right: `Vector { x: 0.0, y: 0.0, z: 0.0 }`', tests/solution_test.rs:145:5

---- solution_test::test_point_distance stdout ----
thread 'solution_test::test_point_distance' panicked at 'assertion failed: (line.distance(p1) - 2.0f64.sqrt() / 2.0).abs() < EPS * 1000.0', tests/solution_test.rs:183:5


failures:
    solution_test::test_equailty_symmetry
    solution_test::test_equality_floating
    solution_test::test_line_equality_by_points
    solution_test::test_line_equality_by_vectors
    solution_test::test_number_vector_multiplication_with_precision
    solution_test::test_point_distance

test result: FAILED. 9 passed; 6 failed; 0 ignored; 0 measured; 0 filtered out

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

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

Димитър качи първо решение на 26.11.2018 16:20 (преди над 4 години)

Коментирах два отделни проблема, и вероятно заради тях гърмят тестовете. Можеш да огледаш останалите домашни за правилни решения, можеш и да си пуснеш пълните тестове и да пробваш сам да си оправиш кода: https://github.com/fmi/rust-homework/blob/master/02/test_full.rs

Проблемът е, че в дискорд не си бях пуснал нотификации и буквално последния ден разбрах, че имаме домашно и го написах на работата и нямах време да го дооправям :D :D пак добре, че съм хванал някви точки