From 0c12fa31c57c03c6287458a0a8aca7afd057baf6 Mon Sep 17 00:00:00 2001 From: sazid Date: Mon, 26 Oct 2020 12:54:32 +0600 Subject: [PATCH 1/2] feat: Add Vec exercises --- exercises/collections/README.md | 20 +++++++++++++++++ exercises/collections/vec1.rs | 25 ++++++++++++++++++++++ exercises/collections/vec2.rs | 38 +++++++++++++++++++++++++++++++++ info.toml | 30 ++++++++++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 exercises/collections/README.md create mode 100644 exercises/collections/vec1.rs create mode 100644 exercises/collections/vec2.rs diff --git a/exercises/collections/README.md b/exercises/collections/README.md new file mode 100644 index 00000000..9ded29a0 --- /dev/null +++ b/exercises/collections/README.md @@ -0,0 +1,20 @@ +### Collections + +Rust’s standard library includes a number of very useful data +structures called collections. Most other data types represent one +specific value, but collections can contain multiple values. Unlike +the built-in array and tuple types, the data these collections point +to is stored on the heap, which means the amount of data does not need +to be known at compile time and can grow or shrink as the program +runs. + +This exercise will get you familiar with two fundamental data +structures that are used very often in Rust programs: + +* A *vector* allows you to store a variable number of values next to + each other. +* A *hash map* allows you to associate a value with a particular key. + You may also know this by the names *map* in C++, *dictionary* in + Python or an *associative array* in other languages. + +[Rust book chapter](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html) diff --git a/exercises/collections/vec1.rs b/exercises/collections/vec1.rs new file mode 100644 index 00000000..ac3d9f1a --- /dev/null +++ b/exercises/collections/vec1.rs @@ -0,0 +1,25 @@ +// vec1.rs +// Your task is to create a `Vec` which holds the exact same elements +// as in the array `a`. +// Make me compile and pass the test! +// Execute the command `rustlings hint collections1` if you need hints. + +// I AM NOT DONE + +fn array_and_vec() -> ([i32; 4], Vec) { + let a = [10, 20, 30, 40]; // a plain array + let v = // TODO: declare your vector here with the macro for vectors + + (a, v) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_array_and_vec_similarity() { + let (a, v) = array_and_vec(); + assert!(a.iter().zip(v.iter()).all(|(x, y)| x == y)); + } +} diff --git a/exercises/collections/vec2.rs b/exercises/collections/vec2.rs new file mode 100644 index 00000000..ec6cfc00 --- /dev/null +++ b/exercises/collections/vec2.rs @@ -0,0 +1,38 @@ +// vec2.rs +// A Vec of even numbers is given. Your task is to complete the loop +// so that each number in the Vec is multiplied by 2. +// +// Make me pass the test! +// +// Execute the command `rustlings hint collections2` if you need +// hints. + +// I AM NOT DONE + +fn vec_loop(mut v: Vec) -> Vec { + for i in v.iter_mut() { + // TODO: Fill this up so that each element in the Vec `v` is + // multiplied by 2. + } + + // At this point, `v` should be equal to [4, 8, 12, 16, 20]. + v +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_vec_loop() { + let v: Vec = (1..).filter(|x| x % 2 == 0).take(5).collect(); + let ans = vec_loop(v.clone()); + + assert_eq!( + ans, + v.iter() + .map(|x| x * 2) + .collect::>() + ); + } +} diff --git a/info.toml b/info.toml index 2d0abdb1..56605a7b 100644 --- a/info.toml +++ b/info.toml @@ -370,6 +370,36 @@ its internal structure (the `fruits` and `veggies` modules and associated constants). It's almost there except for one keyword missing for each constant.""" +# COLLECTIONS + +[[exercises]] +name = "collections1" +path = "exercises/collections/vec1.rs" +mode = "test" +hint = """ +In Rust, there are two ways to define a Vector. + +1. One way is to use the `Vec::new()` function to create a new vector + and fill it with the `push()` method. + +2. The second way, which is simpler is to use the `vec![]` macro and + define your elements inside the square brackets. + +Check this chapter: https://doc.rust-lang.org/stable/book/ch08-01-vectors.html +of the Rust book to learn more. +""" + +[[exercises]] +name = "collections2" +path = "exercises/collections/vec2.rs" +mode = "test" +hint = """ +Hint 1: `i` is each element from the Vec as they are being iterated. + Can you try multiplying this? + +Hint 2: Check the suggestion from the compiler error ;) +""" + # MACROS [[exercises]] From 633c00cf8071e1e82959a3010452a32f34f29fc9 Mon Sep 17 00:00:00 2001 From: sazid Date: Mon, 26 Oct 2020 18:08:48 +0600 Subject: [PATCH 2/2] feat: Add HashMap exercises --- exercises/collections/hashmap1.rs | 46 +++++++++++++++++ exercises/collections/hashmap2.rs | 83 +++++++++++++++++++++++++++++++ info.toml | 22 ++++++++ 3 files changed, 151 insertions(+) create mode 100644 exercises/collections/hashmap1.rs create mode 100644 exercises/collections/hashmap2.rs diff --git a/exercises/collections/hashmap1.rs b/exercises/collections/hashmap1.rs new file mode 100644 index 00000000..b1dc0bbd --- /dev/null +++ b/exercises/collections/hashmap1.rs @@ -0,0 +1,46 @@ +// hashmap1.rs +// A basket of fruits in the form of a hash map needs to be defined. +// The key represents the name of the fruit and the value represents +// how many of that particular fruit is in the basket. You have to put +// at least three different types of fruits (e.g apple, banana, mango) +// in the basket and the total count of all the fruits should be at +// least five. +// +// Make me compile and pass the tests! +// +// Execute the command `rustlings hint collections3` if you need +// hints. + +// I AM NOT DONE + +use std::collections::HashMap; + +fn fruit_basket() -> HashMap { + let mut basket = // TODO: declare your hash map here. + + // Two bananas are already given for you :) + basket.insert(String::from("banana"), 2); + + // TODO: Put more fruits in your basket here. + + basket +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn at_least_three_types_of_fruits() { + let basket = fruit_basket(); + assert!(basket.len() >= 3); + } + + #[test] + fn at_least_five_fruits() { + let basket = fruit_basket(); + assert!(basket + .values() + .sum::() >= 5); + } +} diff --git a/exercises/collections/hashmap2.rs b/exercises/collections/hashmap2.rs new file mode 100644 index 00000000..7e25be7c --- /dev/null +++ b/exercises/collections/hashmap2.rs @@ -0,0 +1,83 @@ +// hashmap2.rs + +// A basket of fruits in the form of a hash map is given. The key +// represents the name of the fruit and the value represents how many +// of that particular fruit is in the basket. You have to put *MORE +// THAN 11* fruits in the basket. Three types of fruits - Apple (4), +// Mango (2) and Lichi (5) are already given in the basket. You are +// not allowed to insert any more of these fruits! +// +// Make me pass the tests! +// +// Execute the command `rustlings hint collections4` if you need +// hints. + +// I AM NOT DONE + +use std::collections::HashMap; + +#[derive(Hash, PartialEq, Eq)] +enum Fruit { + Apple, + Banana, + Mango, + Lichi, + Pineapple, +} + +fn fruit_basket(basket: &mut HashMap) { + let fruit_kinds = vec![ + Fruit::Apple, + Fruit::Banana, + Fruit::Mango, + Fruit::Lichi, + Fruit::Pineapple, + ]; + + for fruit in fruit_kinds { + // TODO: Put new fruits if not already present. Note that you + // are not allowed to put any type of fruit that's already + // present! + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn get_fruit_basket() -> HashMap { + let mut basket = HashMap::::new(); + basket.insert(Fruit::Apple, 4); + basket.insert(Fruit::Mango, 2); + basket.insert(Fruit::Lichi, 5); + + basket + } + + #[test] + fn test_given_fruits_are_not_modified() { + let mut basket = get_fruit_basket(); + fruit_basket(&mut basket); + assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4); + assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2); + assert_eq!(*basket.get(&Fruit::Lichi).unwrap(), 5); + } + + #[test] + fn at_least_five_types_of_fruits() { + let mut basket = get_fruit_basket(); + fruit_basket(&mut basket); + let count_fruit_kinds = basket.len(); + assert!(count_fruit_kinds == 5); + } + + #[test] + fn greater_than_eleven_fruits() { + let mut basket = get_fruit_basket(); + fruit_basket(&mut basket); + let count = basket + .values() + .sum::(); + assert!(count > 11); + } +} diff --git a/info.toml b/info.toml index 56605a7b..c52702f7 100644 --- a/info.toml +++ b/info.toml @@ -400,6 +400,28 @@ Hint 1: `i` is each element from the Vec as they are being iterated. Hint 2: Check the suggestion from the compiler error ;) """ +[[exercises]] +name = "collections3" +path = "exercises/collections/hashmap1.rs" +mode = "test" +hint = """ +Hint 1: Take a look at the return type of the function to figure out + the type for the `basket`. + +Hint 2: Number of fruits should be at least 5. And you have to put + at least three different types of fruits. +""" + +[[exercises]] +name = "collections4" +path = "exercises/collections/hashmap2.rs" +mode = "test" +hint = """ +Use the `entry()` and `or_insert()` methods of `HashMap` to achieve this. + +Learn more at https://doc.rust-lang.org/stable/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value +""" + # MACROS [[exercises]]