diff --git a/subjects/adding_twice/README.md b/subjects/adding_twice/README.md index d47cceda13..573e5cc806 100644 --- a/subjects/adding_twice/README.md +++ b/subjects/adding_twice/README.md @@ -14,7 +14,7 @@ The type of the arguments are missing. Use the example `main` function to determ ```rust pub fn twice(F: _) -> _{ - + todo!() } ``` diff --git a/subjects/closures/README.md b/subjects/closures/README.md index 4f7af2b239..9336c71042 100644 --- a/subjects/closures/README.md +++ b/subjects/closures/README.md @@ -8,7 +8,7 @@ Using closures and iterators create a **function**, that returns the first 50 ev ```rust fn first_fifty_even_square() -> Vec { - + todo!() } ``` @@ -20,7 +20,6 @@ Here is a program to test your function. use closures::*; fn main() { - println!("Hello, world!"); let v1 = first_fifty_even_square(); println!("All elements in {:?}, len = {}", v1, v1.len()); diff --git a/subjects/get_products/README.md b/subjects/get_products/README.md index 4719418721..e810cf7480 100644 --- a/subjects/get_products/README.md +++ b/subjects/get_products/README.md @@ -2,22 +2,24 @@ ### Instructions -Create a function named `get_products` that takes a vector of integers, and returns a vector of the products of each index. +Create a function named `get_products` that takes an array of integers, and returns an array of the products of each other index. -You'll need to return the product of every index -except the current one. +For each element, you'll need to return the product of every other index. + +If an array of one element is given, the same element should always become `1`. ### Example: + For `[1,2,3,4]`, we get: -- for the number `1` we get `2*3*4 = 24`. -- for the number `3` we get `1*2*4 = 8`. +- The element `1` becomes `2*3*4 = 24`. +- The element `3` becomes `1*2*4 = 8`. ### Expected functions ```rust -pub fn get_products(arr: Vec) -> Vec { - +pub fn get_products(arr: [usize; _]) -> [usize; _] { + todo!() } ``` @@ -29,8 +31,7 @@ Here is a program to test your function. use get_products::get_products; fn main() { - let arr: Vec = vec![1, 7, 3, 4]; - let output = get_products(arr); + let output = get_products([1, 7, 3, 4]); println!("{:?}", output); } ``` diff --git a/subjects/highest/README.md b/subjects/highest/README.md index d1f11fcab1..784e475200 100644 --- a/subjects/highest/README.md +++ b/subjects/highest/README.md @@ -2,34 +2,44 @@ ### Instructions -In this exercise, a `Numbers` struct will be given. +In this exercise, a `Numbers` struct will be given. This struct will contain an array of `u32` numbers. These methods have to be written for it: - `new`: create a new instance of `Numbers`. -- `List`: which returns an `array` with every number in the struct. -- `Latest`: which returns an `Option` with the last added number. -- `Highest`: which returns an `Option` with the highest number from the list. -- `Highest_Three`: which returns a `Vec` with the three highest numbers. +- `inner`: which returns the inner array as a slice. +- `last`: which returns an `Option` with the last added number. +- `highest`: which returns an `Option` with the biggest number from the list. +- `highest_three`: which returns an `Option<[u32; 3]>` with the three biggest numbers. These numbers should be ordered. If there aren't three numbers in the array, return `None`. ### Expected functions ```rust #[derive(Debug)] -pub struct Numbers<'a> { - numbers: &'a [u32], +pub struct Numbers { + numbers: [u32; _], } impl Numbers { - pub fn new(numbers: &[u32]) -> Self {} + pub fn new(numbers: [u32; _]) -> Self { + todo!() + } - pub fn list(&self) -> &[u32] {} + pub fn inner(&self) -> &[u32] { + todo!() + } - pub fn latest(&self) -> Option {} + pub fn latest(&self) -> Option { + todo!() + } - pub fn highest(&self) -> Option {} + pub fn highest(&self) -> Option { + todo!() + } - pub fn highest_three(&self) -> Vec {} + pub fn highest_three(&self) -> Option<[u32; 3]> { + todo!() + } } ``` @@ -42,8 +52,8 @@ use highest::*; fn main() { let expected = [30, 500, 20, 70]; - let n = Numbers::new(&expected); - println!("{:?}", n.list()); + let n = Numbers::new(expected); + println!("{:?}", n.inner()); println!("{:?}", n.highest()); println!("{:?}", n.latest()); println!("{:?}", n.highest_three()); @@ -57,7 +67,7 @@ $ cargo run [30, 500, 20, 70] Some(500) Some(70) -[500, 70, 30] +Some([500, 70, 30]) $ ``` diff --git a/subjects/iterators/README.md b/subjects/iterators/README.md index 1071ca2a16..5f13e17a2f 100644 --- a/subjects/iterators/README.md +++ b/subjects/iterators/README.md @@ -11,8 +11,6 @@ Take any positive integer `n`. Repeat the process indefinitely. The conjecture states that no matter which number you start with, you will always reach 1 eventually. -But sometimes the number grow significantly before it reaches 1. This can lead to an integer overflow and makes the algorithm unsolvable within the range of a number in u64. You will not have to worry about that in this exercise. - Given a number `n`, return the number of steps required to reach 1. Examples: @@ -27,6 +25,8 @@ Starting with n = 16, the steps would be as follows: Resulting in 4 steps. So for input n = 16, the return value would be 4. +Depending on the input, the number can grow significantly before it reaches 1. This can lead to an integer overflow and makes the algorithm potentially unsolvable within the range of a u64. We should handle overflow by returning `None`. If the input is invalid, we will also return `None`. We will only consider valid input any positive, non-zero integer. + ### Notions - [Trait Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html) @@ -35,18 +35,9 @@ Resulting in 4 steps. So for input n = 16, the return value would be 4. ### Expected functions ```rust -#[derive(Copy, Clone)] -pub struct Collatz { - pub v: u64, -} - -impl Iterator for Collatz {} - -impl Collatz { - pub fn new(n: u64) -> Self {} +pub fn collatz(n: u64) -> Option { + todo!() } - -pub fn collatz(n: u64) -> usize {} ``` ### Usage @@ -71,12 +62,12 @@ And its output: ```console $ cargo run -0 -0 -2 -5 -8 -16 -9 +None +Some(0) +Some(2) +Some(5) +Some(8) +Some(16) +Some(9) $ ``` diff --git a/subjects/markdown_to_html/README.md b/subjects/markdown_to_html/README.md index 23613147d4..b4c3852e40 100644 --- a/subjects/markdown_to_html/README.md +++ b/subjects/markdown_to_html/README.md @@ -2,18 +2,25 @@ ### Instructions -Create a function which converts markdown into HTML. +Create a function which converts markdown to HTML. +We will be using a modified, simpler version of the [CommonMark](https://commonmark.org/) specification. -To make the task easier you'll only have to account for the first three titles (`#`, `##`, `###`) and for `bold` and `italic` (`**` and `*`). +Here's how your parser should behave: -Parsing and converting markdown can be very tricky and some edge cases can require a lot of time to solve, for this reason we will limit the tests to correct and simple inputs. +- Headers (`# `, `## `, `### `) should be converted to `

`, `

`, `

` tags respectively. +- Bold (`**`) and italic (`*`) should be converted to `` and `` tags respectively. +- Blockquotes (`> `) should be converted to `
` tags. +- Separators (`****`) should be converted to `
` tags. Separators are inline elements, which means there's no content inside them. This means that a `****` should be literally converted to `
`. +- All whitespace should be trimmed and all consecutive newlines should be transformed into a single newline. -No tests will be more complicated than the one showed in the usage example. +Parsing and converting markdown can be particularly tricky for some edge cases. For this reason, we will keep the inputs fairly simple. +No test will be more complicated than the one showed in the usage example. ### Expected Function ```rust pub fn markdown_to_html(s: &str) -> String { + todo!() } ``` @@ -24,7 +31,7 @@ Here is a possible program to test your function, ```rust const EXAMPLE: &str = "# This is a nice converter - ## It handle *all* titles + ## It handles *all* titles ## From # to ### with no problems @@ -33,15 +40,20 @@ const EXAMPLE: &str = "# This is a nice converter > Blockquotes are handled too >if well formatted of course +> test! -And **bold** and *italics* of course work as well. + And **bold** and *italics* of course work as well. **** **bold on multiple lines -also**"; + + +also** + +"; fn main() { println!("{}", markdown_to_html(EXAMPLE)); @@ -53,21 +65,15 @@ And its output: ```console $ cargo run

This is a nice converter

- -

It handle all titles

- +

It handles all titles

From # to ### with no problems

-

With attention to details ;)

###With attention to details ;) -
Blockquotes are handled too
>if well formatted of course - +
test!
And bold and italics of course work as well. - - - +
bold on multiple lines diff --git a/subjects/project_motion/README.md b/subjects/project_motion/README.md index d3c052ad22..b50fec64db 100644 --- a/subjects/project_motion/README.md +++ b/subjects/project_motion/README.md @@ -4,18 +4,18 @@ For this exercise, you will have to create a [projectile motion](https://cimg2.ck12.org/datastreams/f-d%3Abb024be6673110b31e78b46819e792adaed8dc661e082a61f0a6d64e%2BIMAGE%2BIMAGE.1). -Two structures will be provided. A structure called `ThrowObject` that will contain all the variables that are -essential for the projectile physics (initial position, initial velocity, current position, current velocity and time). +Two structures will be provided. A structure called `ThrownObject` that will contain all the variables that are +essential for the projectile physics (initial position and velocity and time elapsed). -A structure called `Object` which will have the corresponding values of X and Y of the initial position, the initial velocity, the current position and the current velocity. +A structure called `Vec2` which represents a scalar with X and Y components. You can use it to represent positions and velocity. -You must implement : +You must implement: -- A function `new` that will initialize the ThrowObject with a given initial position and an initial velocity. -- The trait Iterator with the `.next()` in which the position and speed of the object must be calculated after 1 second. - It will return an `Option` with the ThrowObject, or it will return `None` if the ThrowObject has already reached the floor. +- An associated function `new` that will initialize the `ThrownObject` with a given initial position and velocity. +- The trait `Iterator` where the new position and velocity of the object will be calculated and returned for each second. + It should return the new position and velocity as a tuple, or `None` if the `ThrownObject` has already reached the floor. -Consider the value of gravity is 9.8m/(s*s) and that the position (p) in the instant s of an object is given by: +Consider the value of gravity is 9.8m/s^2 and that the position (p) in the instant s of an object is given by: ![Position Formula](position_formula.png) @@ -23,38 +23,30 @@ and velocity (v) in the instant s of an object is given by: ![Speed Formula](speed_formula.png) - -### Notions - -- [trait Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html) -- [iter](https://doc.rust-lang.org/rust-by-example/trait/iter.html) - ### Expected Function ```rust - -#[derive(Debug, Clone, PartialEq)] -pub struct Object { - pub x: f32, - pub y: f32, +#[derive(Debug, PartialEq, Clone, Copy)] +pub struct Vec2 { + pub x: f64, + pub y: f64, } -#[derive(Debug, Clone, PartialEq)] -pub struct ThrowObject { - pub init_position: Object, - pub init_velocity: Object, - pub actual_position: Object, - pub actual_velocity: Object, - pub time: f32, +#[derive(Debug, PartialEq, Clone, Copy)] +pub struct ThrownObject { + initial_position: Vec2, + initial_velocity: Vec2, + elapsed: f64, } -impl ThrowObject { - pub fn new(init_position: Object, init_velocity: Object) -> ThrowObject { +impl ThrownObject { + pub fn new(position: Vec2, velocity: Vec2) -> Self { + todo!() } } -impl Iterator for ThrowObject { - // next +impl Iterator for ThrownObject { + } ``` @@ -67,8 +59,7 @@ Here is a program to test your function use project_motion::*; fn main() { - let mut obj = ThrowObject::new(Object { x: 50.0, y: 50.0 }, Object { x: 0.0, y: 0.0 }); - println!("{:?}", obj.next()); + let mut obj = ThrownObject::new(Vec2 { x: 50., y: 50. }, Vec2 { x: 0., y: 0. }); println!("{:?}", obj.next()); println!("{:?}", obj.next()); println!("{:?}", obj.next()); @@ -80,10 +71,14 @@ And its output: ```console $ cargo run -Some(ThrowObject { init_position: Object { x: 50.0, y: 50.0 }, init_velocity: Object { x: 0.0, y: 0.0 }, actual_position: Object { x: 50.0, y: 45.1 }, actual_velocity: Object { x: 0.0, y: -9.8 }, time: 1.0 }) -Some(ThrowObject { init_position: Object { x: 50.0, y: 50.0 }, init_velocity: Object { x: 0.0, y: 0.0 }, actual_position: Object { x: 50.0, y: 30.4 }, actual_velocity: Object { x: 0.0, y: -19.6 }, time: 2.0 }) -Some(ThrowObject { init_position: Object { x: 50.0, y: 50.0 }, init_velocity: Object { x: 0.0, y: 0.0 }, actual_position: Object { x: 50.0, y: 5.9 }, actual_velocity: Object { x: 0.0, y: -29.4 }, time: 3.0 }) -None +Some((Vec2 { x: 50.0, y: 45.1 }, Vec2 { x: 0.0, y: -9.8 })) +Some((Vec2 { x: 50.0, y: 30.4 }, Vec2 { x: 0.0, y: -19.6 })) +Some((Vec2 { x: 50.0, y: 5.899999999999999 }, Vec2 { x: 0.0, y: -29.400000000000002 })) None $ ``` + +### Notions + +- [trait Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html) +- [iter](https://doc.rust-lang.org/rust-by-example/trait/iter.html) diff --git a/subjects/roman_numbers_iter/README.md b/subjects/roman_numbers_iter/README.md index 4c9de39d32..2800a51f97 100644 --- a/subjects/roman_numbers_iter/README.md +++ b/subjects/roman_numbers_iter/README.md @@ -2,7 +2,7 @@ ### Instructions -Implement the `Iterator` trait for the `RomanNumber` type. You should use the code from the previous exercise roman_numbers. +Implement the `Iterator` trait for the `RomanNumber` type. You should use the code from the previous exercise `roman_numbers`. ### Notions @@ -21,13 +21,13 @@ impl Iterator for RomanNumber {} Here is a program to test your function. ```rust -use roman_numbers_iterator::RomanNumber; +use roman_numbers_iter::RomanNumber; fn main() { - let mut number = RomanNumber::from(15); + let mut number = RomanNumber::from(15); - println!("{:?}", number); - println!("{:?}", number.next()); + println!("{:?}", number); + println!("{:?}", number.next()); } ``` diff --git a/subjects/sales/README.md b/subjects/sales/README.md index 635fc4aa09..64e248173a 100644 --- a/subjects/sales/README.md +++ b/subjects/sales/README.md @@ -6,35 +6,48 @@ You are going to make a shopping system. It will have a store where the products **"Buy three, get one free".** -The store is having a promotion. The cheapest of three items will be free. But there is a problem with the printer interface, it cannot receive any zero values. We can create a workaround. We will reduce all of the values in the cart by a small amount to show the correct total price. You can see the example to see how it works. +The store is having a promotion. For every three items, the cheapest will be free. But there is a problem with the printer interface: It cannot receive any zero values. We can create a workaround. We will modify the price of all of the items in the cart by a small percentage that will add up to the correct total price. You can find examples below. -You will have to implement for the `Cart` structure the following **functions**: +You will have to implement for the `Cart` structure the following **methods**: -- `new`: that will initialize the cart. -- `insert_item`: will receive a reference to `Store` and a `String`. Just like the name says, it will insert the item to the cart. -- `generate_receipt`: returns a vector of sorted floats. This function must generate the receipt just like the example below, using the promotion. It should save the result in the `receipt` field. +- `new`: will initialize the cart. +- `insert_item_by_name`: will receive a reference to `Store` and a `&str`. As the name suggests, it will insert into the cart the item of the store with the same name. If such item does not exist, it will return `Err(())`. On success, we return `Ok(())`. +- `generate_receipt`: returns a vector of the final prices, sorted. This function must generate the receipt just like the example below, with the promotion applied. ### Expected Function ```rust -#[derive(Debug, Clone, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Item(pub &str, pub f64); + +#[derive(Clone, Copy, Debug, PartialEq)] pub struct Store { - pub products: Vec<(String, f32)>, + pub products: [Item; _], } + impl Store { - pub fn new(products: Vec<(String, f32)>) -> Store { - Store { products } + pub fn new(products: [Item; _]) -> Self { + todo!() } } #[derive(Debug, Clone, PartialEq)] pub struct Cart { - // expected public fields + pub items: Vec, } + impl Cart { - pub fn new() -> Cart {} - pub fn insert_item(&mut self, s: &Store, ele: String) {} - pub fn generate_receipt(&mut self) -> Vec {} + pub fn new() -> Self { + todo!() + } + + pub fn insert_item_by_name(&mut self, s: &Store, name: &str) { + todo!() + } + + pub fn generate_receipt(&self) -> Vec { + todo!() + } } ``` @@ -46,7 +59,7 @@ impl Cart { Because `1.17 + 2.98 + 22.06` == `0 + 3.12 + 23.1` -Floats are rounded with a precision of two decimals which can create small discrepancies as per the example above. +**Floats are rounded with a precision of two decimals** which can create small discrepancies as per the example above. This is a percentage calculation, and it can be applied to a set of three items. If the client purchases 9 items, they will receive three for free, with the discount applied to all items. @@ -54,13 +67,11 @@ This is a percentage calculation, and it can be applied to a set of three items. [1.23, 23.1, 3.12, 9.75, 1.75, 23.75, 2.75, 1.64, 15.23] => [1.16, 1.55, 1.65, 2.6, 2.94, 9.2, 14.38, 21.8, 22.42] ``` - ``` [3.12, 9.75, 1.75, 23.75, 2.75, 1.64, 15.23] => [1.54, 1.65, 2.59, 2.94, 9.18, 14.34, 22.36] ``` -> Hint: Closures are the way. - +> Hint: Closures will be particularly helpful for many of these operations inside lists and vectors. ### Usage @@ -70,21 +81,22 @@ Here is a program to test your function, use sales::*; fn main() { - let store = Store::new(vec![ - (String::from("product A"), 1.23), - (String::from("product B"), 23.1), - (String::from("product C"), 3.12)]); + let store = Store::new([ + Item("product A", 1.23), + Item("product B", 23.1), + Item("product C", 3.12) + ]); println!("{:?}", store); let mut cart = Cart::new(); - cart.insert_item(&store, String::from("product A")); - cart.insert_item(&store, String::from("product B")); - cart.insert_item(&store, String::from("product C")); - - println!("{:?}", cart.generate_receipt()); + cart.insert_item_by_name(&store, "product A").unwrap(); + cart.insert_item_by_name(&store, "product B").unwrap(); + cart.insert_item_by_name(&store, "product C").unwrap(); println!("{:?}", cart); + + println!("{:?}", cart.generate_receipt()); } ``` @@ -92,9 +104,9 @@ And its output: ```console $ cargo run -Store { products: [("product A", 1.23), ("product B", 23.1), ("product C", 3.12)] } +Store { products: [Item("product A", 1.23), Item("product B", 23.1), Item("product C", 3.12)] } +Cart { items: [Item("product A", 1.23), Item("product B", 23.1), Item("product C", 3.12)] } [1.17, 2.98, 22.06] -Cart { items: [("product A", 1.23), ("product B", 23.1), ("product C", 3.12)], receipt: [1.17, 2.98, 22.06] } $ ``` diff --git a/subjects/slices_to_map/README.md b/subjects/slices_to_map/README.md index 7f04ca10da..5d315d6811 100644 --- a/subjects/slices_to_map/README.md +++ b/subjects/slices_to_map/README.md @@ -2,15 +2,15 @@ ### Instructions: - Create a function that borrows two slices and returns a hashmap where the first slice represents the keys and the second represents the values. + - If the slices have different sizes, the function should return the hashmap with the size of the smallest list. ### Expected Function ```rust -pub fn slices_to_map(&[T], &[U]) -> HashMap<&T, &U> { - +pub fn slices_to_map(keys: &[T], values: &[U]) -> HashMap { + todo!() } ``` @@ -22,9 +22,9 @@ Here is a program to test your function. use slices_to_map::*; fn main() { - let keys = ["Olivia", "Liam", "Emma", "Noah", "James"]; - let values = [1, 3, 23, 5, 2]; - println!("{:?}", slices_to_map(&keys, &values)); + let keys = ["Olivia", "Liam", "Emma", "Noah", "James"]; + let values = [1, 3, 23, 5, 2]; + println!("{:?}", slices_to_map(&keys, &values)); } ``` diff --git a/subjects/step_iterator/README.md b/subjects/step_iterator/README.md index 8da1adae48..575ec2fd95 100644 --- a/subjects/step_iterator/README.md +++ b/subjects/step_iterator/README.md @@ -2,29 +2,24 @@ ### Instructions -- Create an `Iterator` (by implementing the `std::iter::Iterator` trait) that iterates through the values from `beg` to `end` (including end) in the indicated `steps`. - - - The name of your iterator will be `StepIterator` and it must be generic so you can use any integer value: i8,..,i64, u8,..,u64 or floating point number f32,..,f64 - +- Create an `Iterator` (by implementing the `std::iter::Iterator` trait) that iterates through the values from `beg` to `end` (including end) by `steps`. + - The name of your iterator will be `StepIterator` and it must be generic enough so that you can use any integer value or floating point number - If the steps do not allow to attain the end of the sequence, only the last value inferior to the end of the series will be returned (See Usage) -- Define the associated function: `new` which creates a new Step iterator: +- Define the associated function `new` which creates a new Step iterator ### Expected Functions and Structures ```rust -pub struct StepIterator { -... -} +pub struct StepIterator {} -use std::ops::Add; impl StepIterator { - pub fn new(beg: T, end: T, step: T) -> Self { - } + pub fn new(beg: T, end: T, step: T) -> Self { + todo!() + } } -impl std::iter::Iterator for StepIterator { -} +impl Iterator for StepIterator {} ``` ### Usage @@ -35,15 +30,8 @@ Here is a program to test your function. use step_iterator::*; fn main() { - for v in StepIterator::new(0, 100, 10) { - print!("{},", v); - } - println!(); - - for v in StepIterator::new(0, 100, 12) { - print!("{},", v) - } - println!(); + println!("{:?}", StepIterator::new(0, 100, 10).collect::>()); + println!("{:?}", StepIterator::new(0, 100, 12).collect::>()); } ``` @@ -51,7 +39,7 @@ And its output: ```console $ cargo run -0,10,20,30,40,50,60,70,80,90,100, -0,12,24,36,48,60,72,84,96, +[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100] +[0, 12, 24, 36, 48, 60, 72, 84, 96] $ ```