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

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

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

Резултати

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

Код

#[derive(Debug)]
pub struct Matrix<T: Clone> {
values: [Cell<T>;4]
}
#[derive(Debug, Clone, PartialEq)]
pub struct Cell<T>(pub T);
impl<T: Clone> Matrix<T> {
/// Данните се очаква да бъдат подадени със статичен масив -- вижте по-долу за примери за
/// конструиране. Какви може да са елементите? Ще тестваме само с два типа: String и i32.
///
/// Очаква се да бъдат подадени по редове, от ляво надясно. Тоест, ако подадем като вход списък
/// с елементи: 1, 2, 3, 4, се очаква конструираната матрица:
///
/// | 1 2 |
/// | 3 4 |
/// Забележете, че подаваме като вход някакъв slice -- reference тип. Не очакваме матрицата да
/// държи reference, клонирайте си данните, за да имате ownership.
///
pub fn new(data: &[T; 4]) -> Matrix<T> {
Matrix {
values: [Cell(data[0].clone()), Cell(data[1].clone()),
Cell(data[2].clone()), Cell(data[3].clone())]
}
}
/// Връща вектор, който съдържа в себе си всички 4 елемента на матрицата, наредени по редове,
/// от ляво надясно и от горе надолу, обвити в `Cell`. Тоест, ако матрицата изглежда така:
///
/// | 1 2 |
/// | 3 4 |
///
/// Очакваме `.by_row` да върне елементите в ред: 1, 2, 3, 4
///
pub fn by_row(&self) -> Vec<Cell<T>> {
self.values.iter().map(|x| x.clone()).collect()
}
/// Връща вектор, който съдържа в себе си всички 4 елемента на матрицата, наредени по колони,
/// от горе надолу и от ляво надясно, Обвити в `Cell`. Тоест, ако матрицата изглежда така:
///
/// | 1 2 |
/// | 3 4 |
///
/// Очакваме `.by_col` да върне елементите в ред: 1, 3, 2, 4
///
pub fn by_col(&self) -> Vec<Cell<T>> {
let mut result: Vec<Cell<T>> = Vec::new();
result.push(self.values[0].clone());
result.push(self.values[2].clone());
result.push(self.values[1].clone());
result.push(self.values[3].clone());
result
}
}
impl std::ops::Add<Cell<String>> for Cell<i32>{
type Output = Cell<String>;
fn add(self, rhs: Cell<String>) -> Self::Output {
let mut result = String::new();
if self.0 >= 0 {
result.push_str(&self.0.to_string());
result.push(' ');
result.push_str(rhs.0.as_str());
} else {
let rev_string: String = rhs.0.chars().rev().collect();
result.push_str(rev_string.as_str());
result.push(' ');
result.push_str(&self.0.abs().to_string());
}
Cell(result)
}
}
impl std::ops::Mul<Cell<String>> for Cell<i32>{
type Output = Cell<String>;
fn mul(self, rhs: Cell<String>) -> Self::Output {
let mut result = String::new();
let mut cnt = self.0;
let mut message = rhs.0;
if cnt < 0 {
cnt = -cnt;
message = message.chars().rev().collect();
}
while cnt > 0 {
result.push_str(&message.as_str());
cnt-=1;
}
Cell(result)
}
}
impl std::ops::Add<Matrix<String>> for Matrix<i32>{
type Output = Matrix<String>;
fn add(self, rhs: Matrix<String>) -> Self::Output {
let upper_left = self.values[0].clone() + rhs.values[0].clone();
let upper_right = self.values[1].clone() + rhs.values[1].clone();
let lower_left = self.values[2].clone() + rhs.values[2].clone();
let lower_right = self.values[3].clone() + rhs.values[3].clone();
Matrix{
values: [upper_left, upper_right, lower_left, lower_right]
}
}
}
impl std::ops::Mul<Matrix<String>> for Matrix<i32>{
type Output = String;
fn mul(self, rhs: Matrix<String>) -> Self::Output {
let mut result = String::new();
let row_traverse = self.by_row();
let column_traverse = rhs.by_col();
for i in 0..row_traverse.len(){
let temp = (row_traverse[i].clone() * column_traverse[i].clone()).0;
result.push_str(temp.as_str());
result.push(' ');
}
result.pop();
result
}
}
#[cfg(test)]
mod tests{
mod matrix_tests{
use crate::*;
#[test]
fn by_row_strings(){
let test_values = ["😂","a","ф","4"];
let matrix = Matrix::new(&test_values);
let actual_result = matrix.by_row();
let expected_result = vec![Cell("😂"),Cell("a"),Cell("ф"),Cell("4")];
assert_eq!(actual_result, expected_result);
}
#[test]
fn by_row_numbers(){
let test_values = [4,3,2,1];
let matrix = Matrix::new(&test_values);
let actual_result = matrix.by_row();
let expected_result = vec![Cell(4),Cell(3),Cell(2),Cell(1)];
assert_eq!(actual_result, expected_result);
}
#[test]
fn by_col_numbers(){
let test_values = [1,2,3,4];
let matrix = Matrix::new(&test_values);
let actual_result = matrix.by_col();
let expected_result = vec![Cell(1),Cell(3),Cell(2),Cell(4)];
assert_eq!(actual_result, expected_result);
}
#[test]
fn by_col_strings(){
let test_values = ["😂","a","ф","4"];
let matrix = Matrix::new(&test_values);
let actual_result = matrix.by_col();
let expected_result = vec![Cell("😂"),Cell("ф"),Cell("a"),Cell("4")];
assert_eq!(actual_result, expected_result);
}
#[test]
fn add_string_matrix_to_number_matrix(){
let number_matrix = Matrix{values:[Cell(1),Cell(-20),Cell(-3),Cell(49)]};
let string_matrix = Matrix{
values:[Cell(String::from("test")), Cell(String::from("eldood")),
Cell(String::from("!7331")), Cell(String::from("skyrim"))]
};
let expected_values = [Cell(String::from("1 test")), Cell(String::from("doodle 20")),
Cell(String::from("1337! 3")), Cell(String::from("49 skyrim"))];
assert_eq!((number_matrix + string_matrix).values, expected_values);
}
#[test]
fn multiply_string_matrix_to_number_matrix(){
let number_matrix = Matrix{values:[Cell(1),Cell(-2),Cell(0),Cell(3)]};
let string_matrix = Matrix{
values:[Cell(String::from("test")), Cell(String::from("eldood")),
Cell(String::from("!7331")), Cell(String::from("skyrim"))]
};
let expected_result = String::from("test 1337!1337! skyrimskyrimskyrim");
assert_eq!(number_matrix*string_matrix, expected_result);
}
#[test]
fn multiply_string_matrix_to_zero_number_matrix(){
let number_matrix = Matrix{values:[Cell(0),Cell(0),Cell(0),Cell(0)]};
let string_matrix = Matrix{
values:[Cell(String::from("test")), Cell(String::from("eldood")),
Cell(String::from("!7331")), Cell(String::from("skyrim"))]
};
let expected_result = String::from(" ");
assert_eq!(number_matrix*string_matrix, expected_result);
}
}
mod cell_tests{
use crate::*;
#[test]
fn add_string_cell_to_non_negative_number_cell(){
assert_eq!(Cell(0)+Cell(String::from("test")), Cell(String::from("0 test")));
assert_eq!(Cell(2)+Cell(String::from("another_test")), Cell(String::from("2 another_test")));
}
#[test]
fn add_string_cell_to_negative_number_cell(){
assert_eq!(Cell(-1)+Cell(String::from("tset")), Cell(String::from("test 1")));
assert_eq!(Cell(-23)+Cell(String::from("moob")), Cell(String::from("boom 23")));
}
#[test]
fn mul_string_cell_to_positive_number_cell(){
assert_eq!(Cell(3)*Cell(String::from("test!")), Cell(String::from("test!test!test!")));
assert_eq!(Cell(1)*Cell(String::from("1337")), Cell(String::from("1337")));
}
#[test]
fn mul_string_cell_to_zero_cell(){
assert_eq!(Cell(0)*Cell(String::from("test!")), Cell(String::from("")));
}
#[test]
fn mul_string_cell_to_negative_number_cell(){
assert_eq!(Cell(-2)*Cell(String::from("!tset")), Cell(String::from("test!test!")));
}
#[test]
fn mul_empty_string_cell_to_positive_number_cell(){
assert_eq!(Cell(10)*Cell(String::from("")), Cell(String::from("")));
}
}
}

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

Compiling solution v0.1.0 (/tmp/d20220112-2706256-1g8k40o/solution)
    Finished test [unoptimized + debuginfo] target(s) in 7.37s
     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 ... ok
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 ... ok

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

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

Даниел качи първо решение на 12.11.2021 22:25 (преди почти 4 години)

Даниел качи решение на 16.11.2021 00:15 (преди почти 4 години)

#[derive(Debug)]
pub struct Matrix<T: Clone> {
values: [Cell<T>;4]
}
#[derive(Debug, Clone, PartialEq)]
pub struct Cell<T>(pub T);
impl<T: Clone> Matrix<T> {
/// Данните се очаква да бъдат подадени със статичен масив -- вижте по-долу за примери за
/// конструиране. Какви може да са елементите? Ще тестваме само с два типа: String и i32.
///
/// Очаква се да бъдат подадени по редове, от ляво надясно. Тоест, ако подадем като вход списък
/// с елементи: 1, 2, 3, 4, се очаква конструираната матрица:
///
/// | 1 2 |
/// | 3 4 |
- ///
/// Забележете, че подаваме като вход някакъв slice -- reference тип. Не очакваме матрицата да
/// държи reference, клонирайте си данните, за да имате ownership.
///
pub fn new(data: &[T; 4]) -> Matrix<T> {
Matrix {
values: [Cell(data[0].clone()), Cell(data[1].clone()),
Cell(data[2].clone()), Cell(data[3].clone())]
}
}
/// Връща вектор, който съдържа в себе си всички 4 елемента на матрицата, наредени по редове,
/// от ляво надясно и от горе надолу, обвити в `Cell`. Тоест, ако матрицата изглежда така:
///
/// | 1 2 |
/// | 3 4 |
///
/// Очакваме `.by_row` да върне елементите в ред: 1, 2, 3, 4
///
pub fn by_row(&self) -> Vec<Cell<T>> {
self.values.iter().map(|x| x.clone()).collect()
}
/// Връща вектор, който съдържа в себе си всички 4 елемента на матрицата, наредени по колони,
/// от горе надолу и от ляво надясно, Обвити в `Cell`. Тоест, ако матрицата изглежда така:
///
/// | 1 2 |
/// | 3 4 |
///
/// Очакваме `.by_col` да върне елементите в ред: 1, 3, 2, 4
///
pub fn by_col(&self) -> Vec<Cell<T>> {
let mut result: Vec<Cell<T>> = Vec::new();
result.push(self.values[0].clone());
result.push(self.values[2].clone());
result.push(self.values[1].clone());
result.push(self.values[3].clone());
result
}
}
impl std::ops::Add<Cell<String>> for Cell<i32>{
type Output = Cell<String>;
fn add(self, rhs: Cell<String>) -> Self::Output {
let mut result = String::new();
- if self.0 > 0 {
+ if self.0 >= 0 {
result.push_str(&self.0.to_string());
result.push(' ');
result.push_str(rhs.0.as_str());
} else {
let rev_string: String = rhs.0.chars().rev().collect();
result.push_str(rev_string.as_str());
result.push(' ');
result.push_str(&self.0.abs().to_string());
}
Cell(result)
}
}
impl std::ops::Mul<Cell<String>> for Cell<i32>{
type Output = Cell<String>;
fn mul(self, rhs: Cell<String>) -> Self::Output {
let mut result = String::new();
let mut cnt = self.0;
let mut message = rhs.0;
if cnt < 0 {
cnt = -cnt;
message = message.chars().rev().collect();
}
while cnt > 0 {
result.push_str(&message.as_str());
cnt-=1;
}
Cell(result)
}
}
impl std::ops::Add<Matrix<String>> for Matrix<i32>{
type Output = Matrix<String>;
fn add(self, rhs: Matrix<String>) -> Self::Output {
let upper_left = self.values[0].clone() + rhs.values[0].clone();
let upper_right = self.values[1].clone() + rhs.values[1].clone();
let lower_left = self.values[2].clone() + rhs.values[2].clone();
let lower_right = self.values[3].clone() + rhs.values[3].clone();
Matrix{
values: [upper_left, upper_right, lower_left, lower_right]
}
}
}
impl std::ops::Mul<Matrix<String>> for Matrix<i32>{
type Output = String;
fn mul(self, rhs: Matrix<String>) -> Self::Output {
let mut result = String::new();
- let mut row_traverse = self.by_row();
- let mut column_traverse = rhs.by_col();
+ let row_traverse = self.by_row();
+ let column_traverse = rhs.by_col();
for i in 0..row_traverse.len(){
let temp = (row_traverse[i].clone() * column_traverse[i].clone()).0;
result.push_str(temp.as_str());
result.push(' ');
}
result.pop();
result
}
}
+
+#[cfg(test)]
+mod tests{
+ mod matrix_tests{
+ use crate::*;
+
+ #[test]
+ fn by_row_strings(){
+ let test_values = ["😂","a","ф","4"];
+ let matrix = Matrix::new(&test_values);
+ let actual_result = matrix.by_row();
+ let expected_result = vec![Cell("😂"),Cell("a"),Cell("ф"),Cell("4")];
+ assert_eq!(actual_result, expected_result);
+ }
+
+ #[test]
+ fn by_row_numbers(){
+ let test_values = [4,3,2,1];
+ let matrix = Matrix::new(&test_values);
+ let actual_result = matrix.by_row();
+ let expected_result = vec![Cell(4),Cell(3),Cell(2),Cell(1)];
+ assert_eq!(actual_result, expected_result);
+ }
+
+ #[test]
+ fn by_col_numbers(){
+ let test_values = [1,2,3,4];
+ let matrix = Matrix::new(&test_values);
+ let actual_result = matrix.by_col();
+ let expected_result = vec![Cell(1),Cell(3),Cell(2),Cell(4)];
+ assert_eq!(actual_result, expected_result);
+ }
+
+ #[test]
+ fn by_col_strings(){
+ let test_values = ["😂","a","ф","4"];
+ let matrix = Matrix::new(&test_values);
+ let actual_result = matrix.by_col();
+ let expected_result = vec![Cell("😂"),Cell("ф"),Cell("a"),Cell("4")];
+ assert_eq!(actual_result, expected_result);
+ }
+
+ #[test]
+ fn add_string_matrix_to_number_matrix(){
+ let number_matrix = Matrix{values:[Cell(1),Cell(-20),Cell(-3),Cell(49)]};
+ let string_matrix = Matrix{
+ values:[Cell(String::from("test")), Cell(String::from("eldood")),
+ Cell(String::from("!7331")), Cell(String::from("skyrim"))]
+ };
+
+ let expected_values = [Cell(String::from("1 test")), Cell(String::from("doodle 20")),
+ Cell(String::from("1337! 3")), Cell(String::from("49 skyrim"))];
+ assert_eq!((number_matrix + string_matrix).values, expected_values);
+ }
+
+ #[test]
+ fn multiply_string_matrix_to_number_matrix(){
+ let number_matrix = Matrix{values:[Cell(1),Cell(-2),Cell(0),Cell(3)]};
+ let string_matrix = Matrix{
+ values:[Cell(String::from("test")), Cell(String::from("eldood")),
+ Cell(String::from("!7331")), Cell(String::from("skyrim"))]
+ };
+
+ let expected_result = String::from("test 1337!1337! skyrimskyrimskyrim");
+ assert_eq!(number_matrix*string_matrix, expected_result);
+ }
+
+ #[test]
+ fn multiply_string_matrix_to_zero_number_matrix(){
+ let number_matrix = Matrix{values:[Cell(0),Cell(0),Cell(0),Cell(0)]};
+ let string_matrix = Matrix{
+ values:[Cell(String::from("test")), Cell(String::from("eldood")),
+ Cell(String::from("!7331")), Cell(String::from("skyrim"))]
+ };
+
+ let expected_result = String::from(" ");
+ assert_eq!(number_matrix*string_matrix, expected_result);
+ }
+ }
+
+ mod cell_tests{
+ use crate::*;
+
+ #[test]
+ fn add_string_cell_to_non_negative_number_cell(){
+ assert_eq!(Cell(0)+Cell(String::from("test")), Cell(String::from("0 test")));
+ assert_eq!(Cell(2)+Cell(String::from("another_test")), Cell(String::from("2 another_test")));
+ }
+
+ #[test]
+ fn add_string_cell_to_negative_number_cell(){
+ assert_eq!(Cell(-1)+Cell(String::from("tset")), Cell(String::from("test 1")));
+ assert_eq!(Cell(-23)+Cell(String::from("moob")), Cell(String::from("boom 23")));
+ }
+
+ #[test]
+ fn mul_string_cell_to_positive_number_cell(){
+ assert_eq!(Cell(3)*Cell(String::from("test!")), Cell(String::from("test!test!test!")));
+ assert_eq!(Cell(1)*Cell(String::from("1337")), Cell(String::from("1337")));
+ }
+
+ #[test]
+ fn mul_string_cell_to_zero_cell(){
+ assert_eq!(Cell(0)*Cell(String::from("test!")), Cell(String::from("")));
+ }
+
+ #[test]
+ fn mul_string_cell_to_negative_number_cell(){
+ assert_eq!(Cell(-2)*Cell(String::from("!tset")), Cell(String::from("test!test!")));
+ }
+
+ #[test]
+ fn mul_empty_string_cell_to_positive_number_cell(){
+ assert_eq!(Cell(10)*Cell(String::from("")), Cell(String::from("")));
+ }
+ }
+
+}