From 7c317f0779ea8decbe4ffb9033de476fa9977a54 Mon Sep 17 00:00:00 2001 From: S P Date: Sat, 5 Aug 2023 21:26:54 +0100 Subject: [PATCH] Steo (#4) * hashmaps * quiz, options * error01 * errors, generics * traits, quiz3 * lifetime, tests * iterators, smart pointers --- exercises/iterators/iterators1.rs | 10 ++++------ exercises/iterators/iterators2.rs | 9 ++++----- exercises/iterators/iterators3.rs | 24 +++++++++++++++++------- exercises/iterators/iterators4.rs | 4 ++-- exercises/iterators/iterators5.rs | 8 ++++---- exercises/lifetimes/lifetimes1.rs | 4 +--- exercises/lifetimes/lifetimes2.rs | 5 ++--- exercises/lifetimes/lifetimes3.rs | 8 +++----- exercises/quiz3.rs | 10 +++++++++- exercises/smart_pointers/arc1.rs | 12 ++++++++---- exercises/smart_pointers/box1.rs | 10 +++++----- exercises/smart_pointers/cow1.rs | 8 ++++++-- exercises/smart_pointers/rc1.rs | 13 ++++++------- exercises/tests/tests1.rs | 4 +--- exercises/tests/tests2.rs | 4 +--- exercises/tests/tests3.rs | 5 ++--- exercises/tests/tests4.rs | 8 ++++---- 17 files changed, 79 insertions(+), 67 deletions(-) diff --git a/exercises/iterators/iterators1.rs b/exercises/iterators/iterators1.rs index b3f698be..2a89ae42 100644 --- a/exercises/iterators/iterators1.rs +++ b/exercises/iterators/iterators1.rs @@ -9,17 +9,15 @@ // Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn main() { let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"]; - let mut my_iterable_fav_fruits = ???; // TODO: Step 1 + let mut my_iterable_fav_fruits = my_fav_fruits.iter(); // TODO: Step 1 assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana")); - assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2 + assert_eq!(my_iterable_fav_fruits.next(), Some(&"custard apple")); // TODO: Step 2 assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado")); - assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3 + assert_eq!(my_iterable_fav_fruits.next(), Some(&"peach")); // TODO: Step 3 assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry")); - assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4 + assert_eq!(my_iterable_fav_fruits.next(), None); // TODO: Step 4 } diff --git a/exercises/iterators/iterators2.rs b/exercises/iterators/iterators2.rs index dda82a08..16ccb422 100644 --- a/exercises/iterators/iterators2.rs +++ b/exercises/iterators/iterators2.rs @@ -6,8 +6,6 @@ // Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - // Step 1. // Complete the `capitalize_first` function. // "hello" -> "Hello" @@ -15,7 +13,7 @@ pub fn capitalize_first(input: &str) -> String { let mut c = input.chars(); match c.next() { None => String::new(), - Some(first) => ???, + Some(first) => format!("{}{}",char::to_uppercase(first), c.as_str()) } } @@ -24,7 +22,8 @@ pub fn capitalize_first(input: &str) -> String { // Return a vector of strings. // ["hello", "world"] -> ["Hello", "World"] pub fn capitalize_words_vector(words: &[&str]) -> Vec { - vec![] + let mut wi = words.iter(); + wi.map(|ww| capitalize_first(ww)).collect::>() } // Step 3. @@ -32,7 +31,7 @@ pub fn capitalize_words_vector(words: &[&str]) -> Vec { // Return a single string. // ["hello", " ", "world"] -> "Hello World" pub fn capitalize_words_string(words: &[&str]) -> String { - String::new() + capitalize_words_vector(words).concat() } #[cfg(test)] diff --git a/exercises/iterators/iterators3.rs b/exercises/iterators/iterators3.rs index 29fa23a3..0c7292d3 100644 --- a/exercises/iterators/iterators3.rs +++ b/exercises/iterators/iterators3.rs @@ -9,8 +9,6 @@ // Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - #[derive(Debug, PartialEq, Eq)] pub enum DivisionError { NotDivisible(NotDivisibleError), @@ -26,23 +24,35 @@ pub struct NotDivisibleError { // Calculate `a` divided by `b` if `a` is evenly divisible by `b`. // Otherwise, return a suitable error. pub fn divide(a: i32, b: i32) -> Result { - todo!(); + match b { + 0 => Err(DivisionError::DivideByZero), + _ => if a % b == 0 { + Ok(a / b) + } else { + Err(DivisionError::NotDivisible(NotDivisibleError { dividend: a, divisor: b })) + } + } } // Complete the function and return a value of the correct type so the test // passes. // Desired output: Ok([1, 11, 1426, 3]) -fn result_with_list() -> () { +fn result_with_list() -> Result, DivisionError> { let numbers = vec![27, 297, 38502, 81]; - let division_results = numbers.into_iter().map(|n| divide(n, 27)); + let division_results = numbers.into_iter() + .flat_map(|n| divide(n, 27)) + .collect::>(); + Ok(division_results) } // Complete the function and return a value of the correct type so the test // passes. // Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)] -fn list_of_results() -> () { +fn list_of_results() -> Vec> { let numbers = vec![27, 297, 38502, 81]; - let division_results = numbers.into_iter().map(|n| divide(n, 27)); + numbers.into_iter() + .map(|n| divide(n, 27)) + .collect::>>() } #[cfg(test)] diff --git a/exercises/iterators/iterators4.rs b/exercises/iterators/iterators4.rs index 79e1692b..cfff0f70 100644 --- a/exercises/iterators/iterators4.rs +++ b/exercises/iterators/iterators4.rs @@ -3,8 +3,6 @@ // Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - pub fn factorial(num: u64) -> u64 { // Complete this function to return the factorial of num // Do not use: @@ -15,6 +13,8 @@ pub fn factorial(num: u64) -> u64 { // For an extra challenge, don't use: // - recursion // Execute `rustlings hint iterators4` for hints. + (1..=num).fold(1u64, |acc, x| acc * x) + } #[cfg(test)] diff --git a/exercises/iterators/iterators5.rs b/exercises/iterators/iterators5.rs index a062ee4c..e3a4edcf 100644 --- a/exercises/iterators/iterators5.rs +++ b/exercises/iterators/iterators5.rs @@ -11,8 +11,6 @@ // Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - use std::collections::HashMap; #[derive(Clone, Copy, PartialEq, Eq)] @@ -35,7 +33,7 @@ fn count_for(map: &HashMap, value: Progress) -> usize { fn count_iterator(map: &HashMap, value: Progress) -> usize { // map is a hashmap with String keys and Progress values. // map = { "variables1": Complete, "from_str": None, ... } - todo!(); + map.values().filter(|x| **x == value).count() } fn count_collection_for(collection: &[HashMap], value: Progress) -> usize { @@ -54,7 +52,9 @@ fn count_collection_iterator(collection: &[HashMap], value: Pr // collection is a slice of hashmaps. // collection = [{ "variables1": Complete, "from_str": None, ... }, // { "variables2": Complete, ... }, ... ] - todo!(); + collection.iter() + .map(|m| count_iterator(m, value)) + .sum() } #[cfg(test)] diff --git a/exercises/lifetimes/lifetimes1.rs b/exercises/lifetimes/lifetimes1.rs index 87bde490..5fe45ae0 100644 --- a/exercises/lifetimes/lifetimes1.rs +++ b/exercises/lifetimes/lifetimes1.rs @@ -8,9 +8,7 @@ // Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - -fn longest(x: &str, y: &str) -> &str { +fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { diff --git a/exercises/lifetimes/lifetimes2.rs b/exercises/lifetimes/lifetimes2.rs index 4f3d8c18..ec5cf92b 100644 --- a/exercises/lifetimes/lifetimes2.rs +++ b/exercises/lifetimes/lifetimes2.rs @@ -6,8 +6,6 @@ // Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x @@ -22,6 +20,7 @@ fn main() { { let string2 = String::from("xyz"); result = longest(string1.as_str(), string2.as_str()); + println!("The longest string is '{}'", result); } - println!("The longest string is '{}'", result); + // solution: or move the string2 to a bigger scope (outside let result...), or move the println inside the small scope } diff --git a/exercises/lifetimes/lifetimes3.rs b/exercises/lifetimes/lifetimes3.rs index 9c59f9c0..aede10de 100644 --- a/exercises/lifetimes/lifetimes3.rs +++ b/exercises/lifetimes/lifetimes3.rs @@ -5,11 +5,9 @@ // Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - -struct Book { - author: &str, - title: &str, +struct Book<'a> { + author: &'a str, + title: &'a str, } fn main() { diff --git a/exercises/quiz3.rs b/exercises/quiz3.rs index 62d4872a..8b923658 100644 --- a/exercises/quiz3.rs +++ b/exercises/quiz3.rs @@ -24,7 +24,15 @@ pub struct ReportCard { pub student_age: u8, } -impl ReportCard { +impl ReportCard { + pub fn new (grade: T, name: String, age: u8) -> Self { + Self { + grade : grade, + student_name : name, + student_age : age, + } + } + pub fn print(&self) -> String { format!("{} ({}) - achieved a grade of {}", &self.student_name, &self.student_age, &self.grade) diff --git a/exercises/smart_pointers/arc1.rs b/exercises/smart_pointers/arc1.rs index 3526ddcb..59cc7cc6 100644 --- a/exercises/smart_pointers/arc1.rs +++ b/exercises/smart_pointers/arc1.rs @@ -21,7 +21,6 @@ // // Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE #![forbid(unused_imports)] // Do not change this, (or the next) line. use std::sync::Arc; @@ -29,15 +28,20 @@ use std::thread; fn main() { let numbers: Vec<_> = (0..100u32).collect(); - let shared_numbers = // TODO + let shared_numbers = Arc::new(numbers); let mut joinhandles = Vec::new(); + println!("Arc counter: {}",Arc::strong_count(&shared_numbers)); for offset in 0..8 { - let child_numbers = // TODO + println!("\n****** Offset {} !!! Arc: {} ", offset, Arc::strong_count(&shared_numbers)); + let child_numbers = Arc::clone(&shared_numbers); + let arcn = Arc::strong_count(&shared_numbers); + println!("After cloning Arc: {}", Arc::strong_count(&shared_numbers)); joinhandles.push(thread::spawn(move || { let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum(); - println!("Sum of offset {} is {}", offset, sum); + println!("{} Arcn) Sum of offset {} is {}", arcn, offset, sum); })); + println!("Arc # {} (handles # {}) ******", arcn, joinhandles.len()); } for handle in joinhandles.into_iter() { handle.join().unwrap(); diff --git a/exercises/smart_pointers/box1.rs b/exercises/smart_pointers/box1.rs index 513e7daa..619ca862 100644 --- a/exercises/smart_pointers/box1.rs +++ b/exercises/smart_pointers/box1.rs @@ -18,11 +18,9 @@ // // Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - #[derive(PartialEq, Debug)] pub enum List { - Cons(i32, List), + Cons(Box, Box), Nil, } @@ -35,11 +33,13 @@ fn main() { } pub fn create_empty_list() -> List { - todo!() + List::Nil } pub fn create_non_empty_list() -> List { - todo!() + List::Cons(Box::new(13), Box::new( + List::Cons(Box::new(12), Box::new(List::Nil)) + )) } #[cfg(test)] diff --git a/exercises/smart_pointers/cow1.rs b/exercises/smart_pointers/cow1.rs index 7ca91686..ce7227c6 100644 --- a/exercises/smart_pointers/cow1.rs +++ b/exercises/smart_pointers/cow1.rs @@ -12,7 +12,6 @@ // // Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE use std::borrow::Cow; @@ -48,7 +47,8 @@ mod tests { let slice = [0, 1, 2]; let mut input = Cow::from(&slice[..]); match abs_all(&mut input) { - // TODO + Cow::Borrowed(_) => Ok(()), + _ => Err("Expected borrowed value"), } } @@ -61,6 +61,8 @@ mod tests { let mut input = Cow::from(slice); match abs_all(&mut input) { // TODO + Cow::Owned(_) => Ok(()), + _ => Err("Expected borrowed value"), } } @@ -73,6 +75,8 @@ mod tests { let mut input = Cow::from(slice); match abs_all(&mut input) { // TODO + Cow::Owned(_) => Ok(()), + _ => Err("Expected owned value"), } } } diff --git a/exercises/smart_pointers/rc1.rs b/exercises/smart_pointers/rc1.rs index ad3f1ce2..e74e6717 100644 --- a/exercises/smart_pointers/rc1.rs +++ b/exercises/smart_pointers/rc1.rs @@ -10,8 +10,6 @@ // // Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - use std::rc::Rc; #[derive(Debug)] @@ -60,17 +58,17 @@ fn main() { jupiter.details(); // TODO - let saturn = Planet::Saturn(Rc::new(Sun {})); + let saturn = Planet::Saturn(Rc::clone(&sun)); println!("reference count = {}", Rc::strong_count(&sun)); // 7 references saturn.details(); // TODO - let uranus = Planet::Uranus(Rc::new(Sun {})); + let uranus = Planet::Uranus(Rc::clone(&sun)); println!("reference count = {}", Rc::strong_count(&sun)); // 8 references uranus.details(); // TODO - let neptune = Planet::Neptune(Rc::new(Sun {})); + let neptune = Planet::Neptune(Rc::clone(&sun)); println!("reference count = {}", Rc::strong_count(&sun)); // 9 references neptune.details(); @@ -92,12 +90,13 @@ fn main() { println!("reference count = {}", Rc::strong_count(&sun)); // 4 references // TODO + drop(earth); println!("reference count = {}", Rc::strong_count(&sun)); // 3 references - // TODO + drop(venus); println!("reference count = {}", Rc::strong_count(&sun)); // 2 references - // TODO + drop(mercury); println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference assert_eq!(Rc::strong_count(&sun), 1); diff --git a/exercises/tests/tests1.rs b/exercises/tests/tests1.rs index 810277ac..eab3ba7a 100644 --- a/exercises/tests/tests1.rs +++ b/exercises/tests/tests1.rs @@ -10,12 +10,10 @@ // Execute `rustlings hint tests1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - #[cfg(test)] mod tests { #[test] fn you_can_assert() { - assert!(); + assert!(true); } } diff --git a/exercises/tests/tests2.rs b/exercises/tests/tests2.rs index f8024e9f..55339213 100644 --- a/exercises/tests/tests2.rs +++ b/exercises/tests/tests2.rs @@ -6,12 +6,10 @@ // Execute `rustlings hint tests2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - #[cfg(test)] mod tests { #[test] fn you_can_assert_eq() { - assert_eq!(); + assert_eq!(1,1); } } diff --git a/exercises/tests/tests3.rs b/exercises/tests/tests3.rs index 4013e384..349e9d46 100644 --- a/exercises/tests/tests3.rs +++ b/exercises/tests/tests3.rs @@ -7,7 +7,6 @@ // Execute `rustlings hint tests3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE pub fn is_even(num: i32) -> bool { num % 2 == 0 @@ -19,11 +18,11 @@ mod tests { #[test] fn is_true_when_even() { - assert!(); + assert!(is_even(4)); } #[test] fn is_false_when_odd() { - assert!(); + assert!(!is_even(3)); } } diff --git a/exercises/tests/tests4.rs b/exercises/tests/tests4.rs index 935d0db1..57dbc530 100644 --- a/exercises/tests/tests4.rs +++ b/exercises/tests/tests4.rs @@ -5,8 +5,6 @@ // Execute `rustlings hint tests4` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - struct Rectangle { width: i32, height: i32 @@ -30,17 +28,19 @@ mod tests { fn correct_width_and_height() { // This test should check if the rectangle is the size that we pass into its constructor let rect = Rectangle::new(10, 20); - assert_eq!(???, 10); // check width - assert_eq!(???, 20); // check height + assert_eq!(rect.width, 10); // check width + assert_eq!(rect.height, 20); // check height } #[test] + #[should_panic] fn negative_width() { // This test should check if program panics when we try to create rectangle with negative width let _rect = Rectangle::new(-10, 10); } #[test] + #[should_panic] fn negative_height() { // This test should check if program panics when we try to create rectangle with negative height let _rect = Rectangle::new(10, -10);