From fb6d440914fe42d78dd84469843da64b19d28158 Mon Sep 17 00:00:00 2001 From: Alexander Baranov Date: Fri, 16 Jan 2026 17:01:52 +0300 Subject: [PATCH] quizzes --- practice/src/bin/e_summary.rs | 24 +++++--- practice/src/bin/f_largest_by_key.rs | 45 +++++++++++--- practice/src/bin/g_draw.rs | 44 ++++++++++++++ practice/src/bin/h_plugins.rs | 53 ++++++++++++++++ practice/src/bin/i_dyn_parser.rs | 70 +++++++++++++++++++++ practice/src/bin/j_sort_strategy.rs | 89 +++++++++++++++++++++++++++ practice/src/bin/k_dyn_logger.rs | 91 ++++++++++++++++++++++++++++ practice/src/bin/l_event_handler.rs | 80 ++++++++++++++++++++++++ 8 files changed, 477 insertions(+), 19 deletions(-) create mode 100644 practice/src/bin/g_draw.rs create mode 100644 practice/src/bin/h_plugins.rs create mode 100644 practice/src/bin/i_dyn_parser.rs create mode 100644 practice/src/bin/j_sort_strategy.rs create mode 100644 practice/src/bin/k_dyn_logger.rs create mode 100644 practice/src/bin/l_event_handler.rs diff --git a/practice/src/bin/e_summary.rs b/practice/src/bin/e_summary.rs index 75f4cf2..f43305e 100644 --- a/practice/src/bin/e_summary.rs +++ b/practice/src/bin/e_summary.rs @@ -1,8 +1,8 @@ // 1. Создайте типаж Summary с методом summarize(&self) -> String. // 2. Реализуйте его длā: -// ○ Vec (где T: ToString), метод должен соединāтþ ÿлементý ùерез запāтуĀ. -// ○ HashMap (где K: ToString, V: ToString), метод должен вýводитþ парý key:value. -// 3. Напиúите функøиĀ print_summary(item: T), котораā пеùатает резулþтат summarize(). +// ○ Vec (где T: ToString), метод должен соединять элементы через запятую. +// ○ HashMap (где K: ToString, V: ToString), метод должен выводить пары key:value. +// 3. Напиúите функøиĀ print_summary(item: T), которая печатает результат summarize(). use std::collections::HashMap; @@ -11,10 +11,16 @@ trait Summary { fn summarize(&self) -> String; } - // Реализация для Vec где T: ToString - - +impl Summary for Vec { + fn summarize(&self) -> String { + self.iter() + .map(|v| v.to_string()) + .collect::>() + .join(",") + .to_string() + } +} // Реализация для HashMap где K: ToString, V: ToString impl Summary for HashMap { @@ -27,9 +33,9 @@ impl Summary for HashMap { } // Обобщённая функция для вывода сводки - - - +fn print_summary(summary: impl Summary) { + println!("{}", summary.summarize()) +} fn main() { // Пример с вектором diff --git a/practice/src/bin/f_largest_by_key.rs b/practice/src/bin/f_largest_by_key.rs index cc38d49..7a6a022 100644 --- a/practice/src/bin/f_largest_by_key.rs +++ b/practice/src/bin/f_largest_by_key.rs @@ -1,12 +1,25 @@ -// Напиúите обобûённуĀ функøиĀ largest_by_key(list: &[T], key: F) -> Option<&T>, где: +// Напиúите обобщенную функцию largest_by_key(list: &[T], key: F) -> Option<&T>, где: // ● F: Fn(&T) -> K, // ● K: PartialOrd. -// Функøиā должна возвраûатþ ÿлемент с максималþнýм знаùением key(item). - -//fn largest_by_key - - +// Функция должна возвращать элемент с максимальным значением key(item). +fn largest_by_key(list: &[T], key: impl Fn(&T) -> K) -> Option<&T> { + let l_len = list.len(); + if l_len < 1 { + return None; + } else if l_len == 1 { + return Some(&list[0]); + } + let mut max = &list[0]; + let mut max_key = key(max); + for element in &list[1..] { + let element_key = key(element); + if element_key > max_key { + (max, max_key) = (element, element_key); + } + } + Some(max) +} fn main() { // Пример из задания @@ -19,11 +32,23 @@ fn main() { let largest_num = largest_by_key(&numbers, |&n| n); println!("{:?}", largest_num); // Some(100) - struct Person { name: String, age: u32 } + struct Person { + name: String, + age: u32, + } let people = [ - Person { name: "Alice".to_string(), age: 30 }, - Person { name: "Bob".to_string(), age: 25 }, - Person { name: "Charlie".to_string(), age: 35 }, + Person { + name: "Alice".to_string(), + age: 30, + }, + Person { + name: "Bob".to_string(), + age: 25, + }, + Person { + name: "Charlie".to_string(), + age: 35, + }, ]; let oldest = largest_by_key(&people, |p| p.age); println!("Oldest: {:?}", oldest.map(|p| &p.name)); // Some("Charlie") diff --git a/practice/src/bin/g_draw.rs b/practice/src/bin/g_draw.rs new file mode 100644 index 0000000..1eafebc --- /dev/null +++ b/practice/src/bin/g_draw.rs @@ -0,0 +1,44 @@ +// Определяем типаж Draw +trait Draw { + fn draw(&self); +} + +// Структура Circle +struct Circle; + +// Реализация Draw для Circle +impl Draw for Circle { + fn draw(&self) { + println!("Drawing circle") + } +} + +// Структура Square +struct Square; + +// Реализация Draw для Square +impl Draw for Square { + fn draw(&self) { + println!("Drawing square") + } +} + +fn main() { + // Создаем гетерогенную коллекцию фигур + let shapes: Vec> = vec![Box::new(Circle), Box::new(Square)]; + + // Рисуем все фигуры + for shape in shapes { + shape.draw(); + } + + // Добавим еще фигур динамически + let mut more_shapes: Vec> = Vec::new(); + more_shapes.push(Box::new(Circle)); + more_shapes.push(Box::new(Square)); + + println!("\nЕще фигуры:"); + for shape in more_shapes { + shape.draw(); + } +} diff --git a/practice/src/bin/h_plugins.rs b/practice/src/bin/h_plugins.rs new file mode 100644 index 0000000..50408f4 --- /dev/null +++ b/practice/src/bin/h_plugins.rs @@ -0,0 +1,53 @@ +use std::time::SystemTime; + +// Определяем типаж Plugin +trait Plugin { + fn execute(&self) -> String; +} + +// Плагин приветствия +struct GreetPlugin; + +impl Plugin for GreetPlugin { + fn execute(&self) -> String { + "Hello, world!".to_string() + } +} + +// Плагин времени +struct TimePlugin; + +impl Plugin for TimePlugin { + fn execute(&self) -> String { + let now = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); + + let seconds = now.as_secs(); + let minutes = seconds / 60; + let hours = (minutes / 60) % 24; + let minutes = minutes % 60; + + format!("Current time: {:02}:{:02}", hours, minutes) + } +} + +fn main() { + // Создаем коллекцию плагинов + let plugins = Vec::>::with_capacity(2); + + // Выполняем все плагины + for plugin in plugins { + println!("{}", plugin.execute()); + } + + // Дополнительный пример с динамическим добавлением + let mut dynamic_plugins: Vec> = Vec::new(); + dynamic_plugins.push(Box::new(GreetPlugin)); + dynamic_plugins.push(Box::new(TimePlugin)); + + println!("\nDynamic execution:"); + for plugin in dynamic_plugins { + println!("{}", plugin.execute()); + } +} diff --git a/practice/src/bin/i_dyn_parser.rs b/practice/src/bin/i_dyn_parser.rs new file mode 100644 index 0000000..0e3eb1a --- /dev/null +++ b/practice/src/bin/i_dyn_parser.rs @@ -0,0 +1,70 @@ +// Определяем типаж Parser +trait Parser { + fn parse(&self, input: &str) -> Result; +} + + + +// Парсер JSON +struct JsonParser; + +impl Parser for JsonParser { + fn parse(&self, input: &str) -> Result { + if input.trim().starts_with('{') && input.trim().ends_with('}') { + Ok("Parsed JSON".to_string()) + } else { + Err("Invalid JSON format".to_string()) + } + } +} + +// Парсер CSV +struct CsvParser; + +impl Parser for CsvParser { + fn parse(&self, input: &str) -> Result { + if input.contains(',') { + Ok("Parsed CSV".to_string()) + } else { + Err("Invalid CSV format".to_string()) + } + } +} + +// Функция для обработки данных парсером +fn parse_data(parser: &dyn Parser, input: &str) -> Result { + parser.parse(input) +} + + + +fn main() { + // Пример использования JSON парсера + let json_parser = JsonParser; + let result = parse_data(&json_parser, r#"{ "name": "Alice" }"#); + println!("{:?}", result); // Ok("Parsed JSON") + + // Пример использования CSV парсера + let csv_parser = CsvParser; + let result = parse_data(&csv_parser, "name,age,location"); + println!("{:?}", result); // Ok("Parsed CSV") + + // Пример обработки ошибок + let invalid_json = parse_data(&json_parser, "not a json"); + println!("{:?}", invalid_json); // Err("Invalid JSON format") + + let invalid_csv = parse_data(&csv_parser, "no commas here"); + println!("{:?}", invalid_csv); // Err("Invalid CSV format") + + // Динамический выбор парсера + let parsers: Vec<&dyn Parser> = vec![&json_parser, &csv_parser]; + for parser in parsers { + println!("Testing parser:"); + let test_input = if parser.parse("{").is_ok() { + r#"{ "test": "value" }"# + } else { + "field1,field2,field3" + }; + println!("{:?}", parser.parse(test_input)); + } +} diff --git a/practice/src/bin/j_sort_strategy.rs b/practice/src/bin/j_sort_strategy.rs new file mode 100644 index 0000000..589b9e0 --- /dev/null +++ b/practice/src/bin/j_sort_strategy.rs @@ -0,0 +1,89 @@ +// Определяем типаж стратегии сортировки +trait SortStrategy { + fn sort(&self, data: &mut [i32]); +} + + +// Реализация пузырьковой сортировки +struct BubbleSort; + +impl SortStrategy for BubbleSort { + fn sort(&self, data: &mut [i32]) { + let len = data.len(); + for i in 0..len { + for j in 0..len - i - 1 { + if data[j] > data[j + 1] { + data.swap(j, j + 1); + } + } + } + } +} + +// Реализация быстрой сортировки +struct QuickSort; + +impl SortStrategy for QuickSort { + fn sort(&self, data: &mut [i32]) { + if data.len() <= 1 { + return; + } + + let pivot = data.len() / 2; + let mut i = 0; + let mut j = data.len() - 1; + + loop { + while data[i] < data[pivot] { + i += 1; + } + while data[j] > data[pivot] { + j -= 1; + } + + if i >= j { + break; + } + + data.swap(i, j); + i += 1; + j -= 1; + } + + self.sort(&mut data[..i]); + self.sort(&mut data[i..]); + } +} + +// Функция для применения стратегии сортировки +fn sort_data(strategy: &dyn SortStrategy, data: &mut [i32]) { + strategy.sort(data) +} + + + +fn main() { + // Тестируем пузырьковую сортировку + let mut data1 = [3, 1, 2, 5, 4]; + let bubble = Box::new(BubbleSort); + sort_data(&*bubble, &mut data1); + println!("Bubble sort: {:?}", data1); // [1, 2, 3, 4, 5] + + // Тестируем быструю сортировку + let mut data2 = [7, 3, 9, 2, 1]; + let quick = Box::new(QuickSort); + sort_data(&*quick, &mut data2); + println!("Quick sort: {:?}", data2); // [1, 2, 3, 7, 9] + + // Динамический выбор стратегии + let strategies: Vec> = vec![ + Box::new(BubbleSort), + Box::new(QuickSort), + ]; + + for strategy in strategies { + let mut test_data = [5, 2, 4, 1, 3]; + strategy.sort(&mut test_data); + println!("Sorted: {:?}", test_data); + } +} diff --git a/practice/src/bin/k_dyn_logger.rs b/practice/src/bin/k_dyn_logger.rs new file mode 100644 index 0000000..414c853 --- /dev/null +++ b/practice/src/bin/k_dyn_logger.rs @@ -0,0 +1,91 @@ +// Уровни логирования +#[derive(Debug, PartialEq, PartialOrd, Copy, Clone)] +enum LogLevel { + Error, + Warn, + Info, + Debug, +} + +// Типаж Logger +trait Logger { + fn log(&self, message: &str); + fn level(&self) -> LogLevel; +} + +// Логгер в консоль +struct ConsoleLogger { + level: LogLevel, +} + +impl ConsoleLogger { + fn new(level: LogLevel) -> Self { + ConsoleLogger { level } + } +} + +impl Logger for ConsoleLogger { + fn log(&self, message: &str) { + println!("[Console] {}", message); + } + + fn level(&self) -> LogLevel { + self.level + } +} + +// Логгер в файл (упрощенная реализация) +struct FileLogger { + level: LogLevel, + file_path: String, +} + +impl FileLogger { + fn new(level: LogLevel, file_path: &str) -> Self { + FileLogger { + level, + file_path: file_path.to_string(), + } + } +} + +impl Logger for FileLogger { + fn log(&self, message: &str) { + println!("[File: {}] {}", self.file_path, message); + // В реальной реализации здесь была бы запись в файл + } + + fn level(&self) -> LogLevel { + self.level + } +} + +// Функция для логирования сообщения с проверкой уровня +fn log_message(logger: &dyn Logger, message: &str) { + if logger.level() >= LogLevel::Info { // Пример: логируем только Info и выше + logger.log(message); + } +} + +fn main() { + // Создаем логгеры + let console_logger = Box::new(ConsoleLogger::new(LogLevel::Info)); + let file_logger = Box::new(FileLogger::new(LogLevel::Debug, "app.log")); + + // Логируем сообщения + log_message(&*console_logger, "Application started"); + log_message(&*file_logger, "Debug information"); + + // Сообщение, которое не будет залогировано (уровень ниже Info) + log_message(&*console_logger, "Trace information"); + + // Динамический выбор логгера + let loggers: Vec> = vec![ + Box::new(ConsoleLogger::new(LogLevel::Warn)), + Box::new(FileLogger::new(LogLevel::Error, "errors.log")), + ]; + + for logger in loggers { + log_message(&*logger, "Testing logger"); + } +} diff --git a/practice/src/bin/l_event_handler.rs b/practice/src/bin/l_event_handler.rs new file mode 100644 index 0000000..147b0b5 --- /dev/null +++ b/practice/src/bin/l_event_handler.rs @@ -0,0 +1,80 @@ +use std::collections::HashMap; + +// Определяем типаж обработчика событий +trait EventHandler { + fn handle(&self, event: &str); +} + +// Обработчик для отправки email +struct EmailHandler; + +impl EventHandler for EmailHandler { + fn handle(&self, event: &str) { + println!("EmailHandler handling event '{}'", event) + } +} + +// Обработчик для сохранения в базу данных +struct DatabaseHandler; + +impl EventHandler for DatabaseHandler { + fn handle(&self, event: &str) { + println!("DatabaseHandler handling event '{}'", event) + } +} + +// Обработчик для логирования +struct LogHandler; + +impl EventHandler for LogHandler { + fn handle(&self, event: &str) { + println!("LogHandler handling event '{}'", event) + } +} + +fn main() { + // Создаем реестр обработчиков событий + let mut handlers: HashMap> = HashMap::new(); + + // Регистрируем обработчики + handlers.insert("email".to_string(), Box::new(EmailHandler)); + handlers.insert("database".to_string(), Box::new(DatabaseHandler)); + handlers.insert("log".to_string(), Box::new(LogHandler)); + + // Обрабатываем события + if let Some(handler) = handlers.get("email") { + handler.handle("New user registration"); + } + + if let Some(handler) = handlers.get("database") { + handler.handle("User data update"); + } + + // Динамическая обработка нескольких событий + let events = vec![ + ("email", "Password reset requested"), + ("database", "Order completed"), + ("log", "System started"), + ("unknown", "This won't be processed"), // Не будет обработано + ]; + + for (event_type, event_data) in events { + if let Some(handler) = handlers.get(event_type) { + handler.handle(event_data); + } else { + println!("No handler registered for event type: {}", event_type); + } + } + + // Добавление нового обработчика во время выполнения + struct NotificationHandler; + + impl EventHandler for NotificationHandler { + fn handle(&self, event: &str) { + println!("Sending push notification: '{}'", event); + } + } + + handlers.insert("notification".to_string(), Box::new(NotificationHandler)); + handlers["notification"].handle("New message received"); +}