Решение на Matrix 4 от Даниел Янев

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

Към профила на Даниел Янев

Резултати

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

Код

use std::ops;
#[derive(Debug)]
pub struct Matrix<T: Clone> {
row: Vec<T>
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Cell<T>(pub T);
impl<T: Clone> Matrix<T> {
pub fn new(data: &[T; 4]) -> Matrix<T> {
Matrix { row: data.iter().cloned().collect() }
}
pub fn new_from_vec(data: Vec<T>) -> Matrix<T> {
if data.len() != 4 {
panic!("Vector of len {} should've been of len 4", data.len())
}
Matrix{row: data}
}
pub fn by_row(&self) -> Vec<Cell<T>> {
self.row.iter().cloned().map(Cell).collect()
}
pub fn by_col(&self) -> Vec<Cell<T>> {
vec![self.row[0].clone(), self.row[2].clone(), self.row[1].clone(), self.row[3].clone()]
.iter()
.cloned()
.map(Cell).collect()
}
}
impl ops::Add<Cell<String>> for Cell<i32> {
type Output = Cell<String>;
fn add(self, other: Cell<String>) -> Cell<String> {
Cell{0: [self.0.to_string(), other.0.clone()].join(" ") }
}
}
impl ops::Mul<Cell<String>> for Cell<i32> {
type Output = Cell<String>;
fn mul(self, other: Cell<String>) -> Cell<String> {
let word: String =
if self.0 < 0 {
other.0.chars().rev().collect::<String>()
} else {
other.0.clone()
};
Cell{0: word.repeat(self.0 as usize)}
}
}

Имаш интересен бъг тук, в тестовете вади "capacity overflow", което не бях виждал досега :D. Проблема е, че ако имаш отрицателно число, го cast-ваш до usize, и това ти вади нещо ужасно голямо, примерно (-3_i32) as usize на моята система вади 18446744073709551613. Ако тук имаше self.0.abs() as usize, щеше да имаш +3 точки.

impl ops::Add<Matrix<String>> for Matrix<i32> {
type Output = Matrix<String>;
fn add(self, other: Matrix<String>) -> Matrix<String> {
let left = self.row.iter().cloned().map(|x| x.to_string());
let result: Vec<String> = left.zip(&other.row).map(|(a, b)| a + " " + b).collect();
return Matrix::new_from_vec(result);
}
}
impl ops::Mul<Matrix<String>> for Matrix<i32> {
type Output = String;
fn mul(self, other: Matrix<String>) -> String {
let numbers = self.by_row().into_iter();
let words = other.by_col().into_iter();
let result: Vec<Cell<String>> = numbers.zip(words).map(|(a, b)| a * b).collect();
result.iter().map(|c| c.0.clone()).collect::<Vec<String>>().join(" ")
}
}

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

Compiling solution v0.1.0 (/tmp/d20220112-2706256-6p1wz7/solution)
    Finished test [unoptimized + debuginfo] target(s) in 8.37s
     Running tests/solution_test.rs (target/debug/deps/solution_test-4c880d3f0adaac34)

running 15 tests
test solution_test::test_adding_int_and_string_negative ... FAILED
test solution_test::test_adding_int_and_string_positive ... ok
test solution_test::test_adding_int_and_string_unicode ... FAILED
test solution_test::test_adding_int_and_string_zero ... ok
test solution_test::test_adding_matrices_1 ... ok
test solution_test::test_adding_matrices_2 ... FAILED
test solution_test::test_blank_strings ... ok
test solution_test::test_iterating_i32s ... ok
test solution_test::test_iterating_strings ... ok
test solution_test::test_multiplying_int_and_string_negative ... FAILED
test solution_test::test_multiplying_int_and_string_positive ... ok
test solution_test::test_multiplying_int_and_string_unicode ... FAILED
test solution_test::test_multiplying_int_and_string_zero ... ok
test solution_test::test_multiplying_matrices_1 ... ok
test solution_test::test_multiplying_matrices_2 ... FAILED

failures:

---- solution_test::test_adding_int_and_string_negative stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `"-2 badger"`,
 right: `"regdab 2"`', tests/solution_test.rs:55:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- solution_test::test_adding_int_and_string_unicode stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `"-3 опа"`,
 right: `"апо 3"`', tests/solution_test.rs:64:5

---- solution_test::test_adding_matrices_2 stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `[Cell("1 едно"), Cell("0 две"), Cell("-3  "), Cell("-37 четири ")]`,
 right: `[Cell("1 едно"), Cell("0 две"), Cell("  3"), Cell(" иритеч 37")]`', tests/solution_test.rs:125:5

---- solution_test::test_multiplying_int_and_string_negative stdout ----
thread 'main' panicked at 'capacity overflow', library/alloc/src/slice.rs:554:50

---- solution_test::test_multiplying_int_and_string_unicode stdout ----
thread 'main' panicked at 'capacity overflow', library/alloc/src/slice.rs:554:50

---- solution_test::test_multiplying_matrices_2 stdout ----
thread 'main' panicked at 'capacity overflow', library/alloc/src/slice.rs:554:50


failures:
    solution_test::test_adding_int_and_string_negative
    solution_test::test_adding_int_and_string_unicode
    solution_test::test_adding_matrices_2
    solution_test::test_multiplying_int_and_string_negative
    solution_test::test_multiplying_int_and_string_unicode
    solution_test::test_multiplying_matrices_2

test result: FAILED. 9 passed; 6 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

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

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

Даниел качи първо решение на 17.11.2021 00:33 (преди почти 4 години)

Защо на ред 78 и 80, collect() не успява да си намери правилния output тип?

Метода collect е полиморфичен по return type, примерно може да използваш Vec, но може и да напишеш:

let result: HashSet<Cell<String>> = numbers.zip(words).map(|(a, b)| a * b).collect();

и ще ти ги събере в HashSet. В случая, HashSet не е import-нато, но Rust не гледа това -- има generic тип T в return type-а (https://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html) и компилатора изисква да укажеш какъв тип искаш.