Решение на Matrix 4 от Павел Атанасов

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

Към профила на Павел Атанасов

Резултати

  • 17 точки от тестове
  • 1 бонус точка
  • 18 точки общо
  • 13 успешни тест(а)
  • 2 неуспешни тест(а)

Код

use std::ops::{Add, Mul};
#[derive(Debug)]
pub struct Matrix<T: Clone> {
data: Vec<Vec<Cell<T>>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Cell<T>(pub T);
impl Add<Cell<String>> for Cell<i32> {
type Output = Cell<String>;
fn add(self, rhs: Cell<String>) -> Self::Output {
Cell(match self.0 < 0 {
true => {
let mut res = rhs.0.chars().rev().collect::<String>();
res.push_str(" ");
res.push_str(&(-self.0).to_string());
res
}
false => {
let mut res = self.0.to_string();
res.push_str(" ");
res.push_str(&rhs.0);
res
}
})
}
}
impl Mul<Cell<String>> for Cell<i32> {
type Output = Cell<String>;
fn mul(self, rhs: Cell<String>) -> Self::Output {
Cell(match self.0 < 0 {
true => rhs
.0
.chars()
.rev()
.cycle()
.take(rhs.0.len() * -self.0 as usize)
.collect(),
false => rhs
.0
.chars()
.cycle()
.take(rhs.0.len() * self.0 as usize)
.collect(),

Харесва ми начина, по който си имплементирал решението със .cycle(), и още повече ми харесва тънкия бъг, който ми отне известно време да разбера -- take-ваш дължината на низа в байтове с .len(), затова тестовете се чупят.

})
}
}
impl<T: Clone> Matrix<T> {
pub fn new(data: &[T; 4]) -> Matrix<T> {
Matrix {
data: data
.clone()
.map(Cell)
.chunks(2)
.map(|row| row.to_owned())
.collect(),
}
}
pub fn by_row(&self) -> Vec<Cell<T>> {
self.data.iter().cloned().flatten().collect()
}
pub fn by_col(&self) -> Vec<Cell<T>> {
let mut transposed_data = self.by_row();
transposed_data.swap(1, 2);
transposed_data
}
}
impl<T: Clone + PartialEq> PartialEq for Matrix<T> {
fn eq(&self, other: &Self) -> bool {
self.data
.iter()
.flatten()
.zip(other.data.iter().flatten())
.map(|(a, b)| a.0 == b.0)
.reduce(|val1, val2| val1 && val2)
.unwrap_or(true)
}
}
impl Add<Matrix<String>> for Matrix<i32> {
type Output = Matrix<String>;
fn add(self, rhs: Matrix<String>) -> Self::Output {
Matrix {
data: self
.by_row()
.iter()
.zip(rhs.by_row().iter())
.map(|(a, b)| a.clone() + b.clone())
.collect::<Vec<Cell<String>>>()
.chunks(2)
.map(|row| row.to_owned())
.collect(),
}
}
}
impl Mul<Matrix<String>> for Matrix<i32> {
type Output = String;
fn mul(self, rhs: Matrix<String>) -> Self::Output {
self.by_row()
.iter()
.zip(rhs.by_col().iter())
.map(|(a, b)| a.clone() * b.clone())
.map(|a| a.0)
.reduce(|str1, str2| str1 + " " + &str2)
.unwrap_or(String::from(""))
}
}
#[cfg(test)]
mod tests {
use crate::{Cell, Matrix};
#[test]
fn test_matrix_by_row() {
let mat = Matrix::new(&[1, 2, 3, 4]);
assert_eq!(mat.by_row(), vec![Cell(1), Cell(2), Cell(3), Cell(4)]);
}
#[test]
fn test_matrix_by_col() {
let mat = Matrix::new(&[1, 2, 3, 4]);
assert_eq!(mat.by_col(), vec![Cell(1), Cell(3), Cell(2), Cell(4)]);
}
#[test]
fn test_cell_add_positive() {
let cell_number: Cell<i32> = Cell(101);
let cell_string: Cell<String> = Cell(String::from("top kek"));
assert_eq!(cell_number + cell_string, Cell(String::from("101 top kek")));
}
#[test]
fn test_cell_add_negative() {
let cell_number: Cell<i32> = Cell(-727);
let cell_string: Cell<String> = Cell(String::from("ISYW"));
assert_eq!(cell_number + cell_string, Cell(String::from("WYSI 727")));
}
#[test]
fn test_cell_mul_positive() {
let cell_number: Cell<i32> = Cell(3);
let cell_string: Cell<String> = Cell(String::from("Vi "));
assert_eq!(cell_number * cell_string, Cell(String::from("Vi Vi Vi ")))
}
#[test]
fn test_cell_mul_negative() {
let cell_number: Cell<i32> = Cell(-2);
let cell_string: Cell<String> = Cell(String::from("!kconK"));
assert_eq!(
cell_number * cell_string,
Cell(String::from("Knock!Knock!"))
)
}
#[test]
fn test_cell_mul_zero() {
let cell_number: Cell<i32> = Cell(0);
let cell_string: Cell<String> = Cell(String::from("KaKa"));
assert_eq!(cell_number * cell_string, Cell(String::from("")))
}
#[test]
fn test_matrix_add_positive() {
let matrix_number: Matrix<i32> = Matrix::new(&[1, 2, 3, 4]);
let matrix_string: Matrix<String> = Matrix::new(&[
String::from("one"),
String::from("two"),
String::from("three"),
String::from("four"),
]);
assert_eq!(
matrix_number + matrix_string,
Matrix::new(&[
String::from("1 one"),
String::from("2 two"),
String::from("3 three"),
String::from("4 four")
])
);
}
#[test]
fn test_matrix_mul_positive() {
let matrix_number: Matrix<i32> = Matrix::new(&[1, 2, 3, 1]);
let matrix_string: Matrix<String> = Matrix::new(&[
String::from("one"),
String::from("two"),
String::from("three"),
String::from("you get it"),
]);
assert_eq!(
matrix_number * matrix_string,
"one threethree twotwotwo you get it"
);
}
}

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

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

running 15 tests
test solution_test::test_adding_int_and_string_negative ... ok
test solution_test::test_adding_int_and_string_positive ... ok
test solution_test::test_adding_int_and_string_unicode ... ok
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 ... ok
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 ... ok
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_multiplying_int_and_string_unicode stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `"опаопаопаопа"`,
 right: `"опаопа"`', tests/solution_test.rs:96:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- solution_test::test_multiplying_matrices_2 stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `"едноедно  евдевдевдевдевдевд  иритеч иритеч иритеч ирит"`,
 right: `"едно  евдевдевд  иритеч иритеч"`', tests/solution_test.rs:153:5


failures:
    solution_test::test_multiplying_int_and_string_unicode
    solution_test::test_multiplying_matrices_2

test result: FAILED. 13 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

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

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

Павел качи първо решение на 12.11.2021 21:15 (преди почти 4 години)

Павел качи решение на 17.11.2021 18:35 (преди почти 4 години)

use std::ops::{Add, Mul};
#[derive(Debug)]
pub struct Matrix<T: Clone> {
data: Vec<Vec<Cell<T>>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Cell<T>(pub T);
impl Add<Cell<String>> for Cell<i32> {
type Output = Cell<String>;
fn add(self, rhs: Cell<String>) -> Self::Output {
Cell(match self.0 < 0 {
true => {
- let mut res = rhs.0.clone().chars().rev().collect::<String>();
+ let mut res = rhs.0.chars().rev().collect::<String>();
res.push_str(" ");
res.push_str(&(-self.0).to_string());
res
}
false => {
- let mut res = self.0.clone().to_string();
+ let mut res = self.0.to_string();
res.push_str(" ");
res.push_str(&rhs.0);
res
}
})
}
}
impl Mul<Cell<String>> for Cell<i32> {
type Output = Cell<String>;
fn mul(self, rhs: Cell<String>) -> Self::Output {
Cell(match self.0 < 0 {
true => rhs
.0
.chars()
.rev()
.cycle()
.take(rhs.0.len() * -self.0 as usize)
.collect(),
false => rhs
.0
.chars()
.cycle()
.take(rhs.0.len() * self.0 as usize)
.collect(),
})
}
}
impl<T: Clone> Matrix<T> {
pub fn new(data: &[T; 4]) -> Matrix<T> {
Matrix {
data: data
.clone()
- .map(|elem| Cell(elem))
+ .map(Cell)
.chunks(2)
- .map(move |row| row.to_owned())
+ .map(|row| row.to_owned())
.collect(),
}
}
pub fn by_row(&self) -> Vec<Cell<T>> {
self.data.iter().cloned().flatten().collect()
}
pub fn by_col(&self) -> Vec<Cell<T>> {
let mut transposed_data = self.by_row();
transposed_data.swap(1, 2);
transposed_data
}
}
impl<T: Clone + PartialEq> PartialEq for Matrix<T> {
fn eq(&self, other: &Self) -> bool {
self.data
.iter()
.flatten()
.zip(other.data.iter().flatten())
.map(|(a, b)| a.0 == b.0)
.reduce(|val1, val2| val1 && val2)
.unwrap_or(true)
}
}
impl Add<Matrix<String>> for Matrix<i32> {
type Output = Matrix<String>;
fn add(self, rhs: Matrix<String>) -> Self::Output {
Matrix {
data: self
.by_row()
.iter()
.zip(rhs.by_row().iter())
.map(|(a, b)| a.clone() + b.clone())
.collect::<Vec<Cell<String>>>()
.chunks(2)
- .map(move |row| row.to_owned())
+ .map(|row| row.to_owned())
.collect(),
}
}
}
impl Mul<Matrix<String>> for Matrix<i32> {
type Output = String;
fn mul(self, rhs: Matrix<String>) -> Self::Output {
self.by_row()
.iter()
.zip(rhs.by_col().iter())
.map(|(a, b)| a.clone() * b.clone())
.map(|a| a.0)
.reduce(|str1, str2| str1 + " " + &str2)
.unwrap_or(String::from(""))
}
}
#[cfg(test)]
mod tests {
use crate::{Cell, Matrix};
#[test]
fn test_matrix_by_row() {
let mat = Matrix::new(&[1, 2, 3, 4]);
assert_eq!(mat.by_row(), vec![Cell(1), Cell(2), Cell(3), Cell(4)]);
}
#[test]
fn test_matrix_by_col() {
let mat = Matrix::new(&[1, 2, 3, 4]);
assert_eq!(mat.by_col(), vec![Cell(1), Cell(3), Cell(2), Cell(4)]);
}
#[test]
fn test_cell_add_positive() {
let cell_number: Cell<i32> = Cell(101);
let cell_string: Cell<String> = Cell(String::from("top kek"));
assert_eq!(cell_number + cell_string, Cell(String::from("101 top kek")));
}
#[test]
fn test_cell_add_negative() {
let cell_number: Cell<i32> = Cell(-727);
let cell_string: Cell<String> = Cell(String::from("ISYW"));
assert_eq!(cell_number + cell_string, Cell(String::from("WYSI 727")));
}
#[test]
fn test_cell_mul_positive() {
let cell_number: Cell<i32> = Cell(3);
let cell_string: Cell<String> = Cell(String::from("Vi "));
assert_eq!(cell_number * cell_string, Cell(String::from("Vi Vi Vi ")))
}
#[test]
fn test_cell_mul_negative() {
let cell_number: Cell<i32> = Cell(-2);
let cell_string: Cell<String> = Cell(String::from("!kconK"));
assert_eq!(
cell_number * cell_string,
Cell(String::from("Knock!Knock!"))
)
}
#[test]
fn test_cell_mul_zero() {
let cell_number: Cell<i32> = Cell(0);
let cell_string: Cell<String> = Cell(String::from("KaKa"));
assert_eq!(cell_number * cell_string, Cell(String::from("")))
}
#[test]
fn test_matrix_add_positive() {
let matrix_number: Matrix<i32> = Matrix::new(&[1, 2, 3, 4]);
let matrix_string: Matrix<String> = Matrix::new(&[
String::from("one"),
String::from("two"),
String::from("three"),
String::from("four"),
]);
assert_eq!(
matrix_number + matrix_string,
Matrix::new(&[
String::from("1 one"),
String::from("2 two"),
String::from("3 three"),
String::from("4 four")
])
);
}
#[test]
fn test_matrix_mul_positive() {
let matrix_number: Matrix<i32> = Matrix::new(&[1, 2, 3, 1]);
let matrix_string: Matrix<String> = Matrix::new(&[
String::from("one"),
String::from("two"),
String::from("three"),
String::from("you get it"),
]);
assert_eq!(
matrix_number * matrix_string,
"one threethree twotwotwo you get it"
);
}
}

Павел качи решение на 18.11.2021 12:29 (преди почти 4 години)

use std::ops::{Add, Mul};
#[derive(Debug)]
pub struct Matrix<T: Clone> {
data: Vec<Vec<Cell<T>>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Cell<T>(pub T);
impl Add<Cell<String>> for Cell<i32> {
type Output = Cell<String>;
fn add(self, rhs: Cell<String>) -> Self::Output {
Cell(match self.0 < 0 {
true => {
let mut res = rhs.0.chars().rev().collect::<String>();
res.push_str(" ");
res.push_str(&(-self.0).to_string());
res
}
false => {
let mut res = self.0.to_string();
res.push_str(" ");
res.push_str(&rhs.0);
res
}
})
}
}
impl Mul<Cell<String>> for Cell<i32> {
type Output = Cell<String>;
fn mul(self, rhs: Cell<String>) -> Self::Output {
Cell(match self.0 < 0 {
true => rhs
.0
.chars()
.rev()
.cycle()
.take(rhs.0.len() * -self.0 as usize)
.collect(),
false => rhs
.0
.chars()
.cycle()
.take(rhs.0.len() * self.0 as usize)
.collect(),

Харесва ми начина, по който си имплементирал решението със .cycle(), и още повече ми харесва тънкия бъг, който ми отне известно време да разбера -- take-ваш дължината на низа в байтове с .len(), затова тестовете се чупят.

})
}
}
impl<T: Clone> Matrix<T> {
pub fn new(data: &[T; 4]) -> Matrix<T> {
Matrix {
data: data
.clone()
.map(Cell)
.chunks(2)
.map(|row| row.to_owned())
.collect(),
}
}
pub fn by_row(&self) -> Vec<Cell<T>> {
self.data.iter().cloned().flatten().collect()
}
pub fn by_col(&self) -> Vec<Cell<T>> {
let mut transposed_data = self.by_row();
transposed_data.swap(1, 2);
transposed_data
}
}
impl<T: Clone + PartialEq> PartialEq for Matrix<T> {
fn eq(&self, other: &Self) -> bool {
self.data
.iter()
.flatten()
.zip(other.data.iter().flatten())
.map(|(a, b)| a.0 == b.0)
.reduce(|val1, val2| val1 && val2)
.unwrap_or(true)
}
}
impl Add<Matrix<String>> for Matrix<i32> {
type Output = Matrix<String>;
fn add(self, rhs: Matrix<String>) -> Self::Output {
Matrix {
data: self
.by_row()
.iter()
.zip(rhs.by_row().iter())
.map(|(a, b)| a.clone() + b.clone())
.collect::<Vec<Cell<String>>>()
.chunks(2)
.map(|row| row.to_owned())
.collect(),
}
}
}
impl Mul<Matrix<String>> for Matrix<i32> {
type Output = String;
fn mul(self, rhs: Matrix<String>) -> Self::Output {
self.by_row()
.iter()
.zip(rhs.by_col().iter())
.map(|(a, b)| a.clone() * b.clone())
.map(|a| a.0)
.reduce(|str1, str2| str1 + " " + &str2)
.unwrap_or(String::from(""))
- }
+ }
}
#[cfg(test)]
mod tests {
use crate::{Cell, Matrix};
#[test]
fn test_matrix_by_row() {
let mat = Matrix::new(&[1, 2, 3, 4]);
assert_eq!(mat.by_row(), vec![Cell(1), Cell(2), Cell(3), Cell(4)]);
}
#[test]
fn test_matrix_by_col() {
let mat = Matrix::new(&[1, 2, 3, 4]);
assert_eq!(mat.by_col(), vec![Cell(1), Cell(3), Cell(2), Cell(4)]);
}
#[test]
fn test_cell_add_positive() {
let cell_number: Cell<i32> = Cell(101);
let cell_string: Cell<String> = Cell(String::from("top kek"));
assert_eq!(cell_number + cell_string, Cell(String::from("101 top kek")));
}
#[test]
fn test_cell_add_negative() {
let cell_number: Cell<i32> = Cell(-727);
let cell_string: Cell<String> = Cell(String::from("ISYW"));
assert_eq!(cell_number + cell_string, Cell(String::from("WYSI 727")));
}
#[test]
fn test_cell_mul_positive() {
let cell_number: Cell<i32> = Cell(3);
let cell_string: Cell<String> = Cell(String::from("Vi "));
assert_eq!(cell_number * cell_string, Cell(String::from("Vi Vi Vi ")))
}
#[test]
fn test_cell_mul_negative() {
let cell_number: Cell<i32> = Cell(-2);
let cell_string: Cell<String> = Cell(String::from("!kconK"));
assert_eq!(
cell_number * cell_string,
Cell(String::from("Knock!Knock!"))
)
}
#[test]
fn test_cell_mul_zero() {
let cell_number: Cell<i32> = Cell(0);
let cell_string: Cell<String> = Cell(String::from("KaKa"));
assert_eq!(cell_number * cell_string, Cell(String::from("")))
}
#[test]
fn test_matrix_add_positive() {
let matrix_number: Matrix<i32> = Matrix::new(&[1, 2, 3, 4]);
let matrix_string: Matrix<String> = Matrix::new(&[
String::from("one"),
String::from("two"),
String::from("three"),
String::from("four"),
]);
assert_eq!(
matrix_number + matrix_string,
Matrix::new(&[
String::from("1 one"),
String::from("2 two"),
String::from("3 three"),
String::from("4 four")
])
);
}
#[test]
fn test_matrix_mul_positive() {
let matrix_number: Matrix<i32> = Matrix::new(&[1, 2, 3, 1]);
let matrix_string: Matrix<String> = Matrix::new(&[
String::from("one"),
String::from("two"),
String::from("three"),
String::from("you get it"),
]);
assert_eq!(
matrix_number * matrix_string,
"one threethree twotwotwo you get it"
);
}
}

Написал ти тестове за всичката функционалност, но си изпуснал интересните case-ове: празни низове и кирилица. Ако беше пробвал с кирилица, може би щеше и да си намериш бъга.

Все пак ми харесва и решението със .cycle(), така че ще ти дам бонус точка като първия пуснал такава имплементация 👍.