From 342b1d50b9ce80a3efc371a3b5db288f4b375600 Mon Sep 17 00:00:00 2001 From: Rhinemann Date: Wed, 21 Jun 2023 00:33:57 +0300 Subject: [PATCH] Lab 2 in Rust. --- Rust/lab_2/Cargo.lock | 9 +++ Rust/lab_2/Cargo.toml | 1 + Rust/lab_2/src/main.rs | 132 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 140 insertions(+), 2 deletions(-) diff --git a/Rust/lab_2/Cargo.lock b/Rust/lab_2/Cargo.lock index 90cd794..bb4e6f4 100644 --- a/Rust/lab_2/Cargo.lock +++ b/Rust/lab_2/Cargo.lock @@ -5,3 +5,12 @@ version = 3 [[package]] name = "lab_2" version = "0.1.0" +dependencies = [ + "text_io", +] + +[[package]] +name = "text_io" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f0c8eb2ad70c12a6a69508f499b3051c924f4b1cfeae85bfad96e6bc5bba46" diff --git a/Rust/lab_2/Cargo.toml b/Rust/lab_2/Cargo.toml index 4f144c0..09e0b0a 100644 --- a/Rust/lab_2/Cargo.toml +++ b/Rust/lab_2/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +text_io = "0.1.12" diff --git a/Rust/lab_2/src/main.rs b/Rust/lab_2/src/main.rs index fbedd92..f6f8591 100644 --- a/Rust/lab_2/src/main.rs +++ b/Rust/lab_2/src/main.rs @@ -1,3 +1,131 @@ +// #[allow(dead_code)] +fn capitalise(s: &str) -> String { + let mut c = s.chars(); + match c.next() { + None => String::new(), + Some(f) => f.to_uppercase().collect::() + c.as_str(), + } +} + +fn read_row() -> Vec { + loop { + print!("Row (separated by spaces): "); + let raw_row: String = text_io::read!("{}\n"); + let trimmed_row: &str = raw_row.trim(); + match trimmed_row.split(" ").all(|value| { + value.chars().all(|char| char.is_numeric()) + && value.parse::().unwrap() <= i16::MAX as i32 + && value.parse::().unwrap() >= i16::MIN as i32 + }) { + true => { + return trimmed_row + .split(" ") + .map(|value| value.parse::().unwrap()) + .collect::>() + } + false => println!("[Error] The row must consist of short integers, try again."), + } + } +} + +fn generate_row(row_index: u16, length: u16) -> Vec { + return (0..length) + .map(|element_index| (element_index as i16 + 1) * (row_index as i16 + 1)) + .collect(); +} + +fn read_matrix() -> Vec> { + let rows: u16 = protected_u16_read("the number of rows"); + loop { + print!("Generate matrix or input manually [g/i]: "); + let option: String = text_io::read!(); + match option.to_lowercase().as_str() { + "g" => { + let columns: u16 = protected_u16_read("the number of columns"); + return (0..rows).map(|i| generate_row(i, columns)).collect(); + } + "i" => return (0..rows).map(|_| read_row()).collect(), + _ => println!("[Error] Not an option, try again."), + } + } +} + +fn protected_u16_read(variable_name: &str) -> u16 { + use text_io::try_read; + loop { + print!("Enter {}: ", variable_name); + let read_result: Result = try_read!(); + match read_result { + Ok(read_integer) => return read_integer, + Err(_e) => println!( + "{} must be a short integer, try again.", + capitalise(variable_name) + ), + } + } +} + +fn multiply_matrix_by_number(matrix: &Vec>, multiplier: u16) -> Vec> { + return matrix + .iter() + .map(|row| { + row.iter() + .map(|element| element * multiplier as i16) + .collect() + }) + .collect(); +} + +fn average_of_row(row: &Vec) -> f32 { + return row.iter().sum::() as f32 / row.len() as f32; +} + +fn format_matrix(matrix: &Vec>) -> String { + let max_element_width = matrix + .iter() + .map(|row| row.iter().max().unwrap()) + .max() + .unwrap() + .to_string() + .len(); + let min_element_width = matrix + .iter() + .map(|row| row.iter().min().unwrap()) + .min() + .unwrap() + .to_string() + .len(); + + let max_width = max_element_width.max(min_element_width); + + let mut formatted_matrix: String = matrix + .iter() + .map(|row| { + row.iter() + .map(|element| format!("| {:max_width$} ", element)) + .collect::>() + .join("") + }) + .collect::>() + .join("|\n"); + formatted_matrix.push('|'); + return formatted_matrix; +} + fn main() { - println!("Hello, world!"); -} \ No newline at end of file + let full_vec_test: Vec> = read_matrix(); + println!("\nMatrix B:\n{}\n", format_matrix(&full_vec_test)); + + let mult_full_vec_test: Vec> = + multiply_matrix_by_number(&full_vec_test, protected_u16_read("matrix multiplier")); + println!("Matrix a×B:\n{}\n", format_matrix(&mult_full_vec_test)); + + let row_averages: Vec = mult_full_vec_test + .iter() + .map(|row| average_of_row(row)) + .collect(); + println!("Averages for each row in a×B:"); + row_averages + .iter() + .for_each(|element| println!("{}", element)) +}