diff --git a/subjects/does_it_fit/README.md b/subjects/does_it_fit/README.md new file mode 100644 index 000000000..e6f5ed6ae --- /dev/null +++ b/subjects/does_it_fit/README.md @@ -0,0 +1,84 @@ +## doe_it_fit + +### Instructions + +Using the `areas_volumes` module provided, create two functions: + +- `area_fit` that receives 6 arguments: + + - `x` and `y`, size of the square in which it is going to be tried to fit the geometrical shapes (both usize) + - `objects`, the type of geometrical shape(s) that it is going to be tried to be fitted in the square (areas_volumes::GeometricalShapes) + - `times`, the number of geometrical shapes that are going to be tried to be fitted in the square (usize) + - `a` and `b`, the dimensions that the plane(s) shape(s) passed will have (both usize) + - `a` will refer to the side of the Square, the radius of the Circle, the side_a of the Rectangle or the base of the Triangle + - `b` will refer to the side_b of the Rectangle or the height of the Triangle + +- `area_fit` should return if the geometrical shape(s) fit inside of the square. + - `volume_fit` that receives 8 arguments: + - `x`, `y` and `z`, size of the box in which it is going to be tried to fit the geometrical volumes (both usize) + - `objects`, the type of geometrical volume(s) that it is going to be tried to be fitted in the box (areas_volumes::GeometricalVolumes) + - `times`, the number of geometrical volumes that are going to be tried to be fitted in the box (usize) + - `a`, `b` and `c`, the dimensions that the geometrical volume(s) passed will have (all of them usize) + - `a` will refer to the side of the Cube, the radius of the Sphere, the side_a of the Parallelepiped, the area of the base of the Triangular Pyramid or the base radius of the Cone + - `b` will refer to the side_b of the Parallelepiped, the height of the Triangular Pyramid or the height of the Cone + - `c` will refer to the side_c of the Parallelepiped +- `volume_fit` should return if the geometrical volume(s) fit inside of the box. + +### Expected Functions (and Structures) + +```rs +pub fn area_fit( + x: usize, + y: usize, + objects: areas_volumes::GeometricalShapes, + times: usize, + a: usize, + b: usize, +) {} +pub fn volume_fit( + x: usize, + y: usize, + z: usize, + objects: areas_volumes::GeometricalVolumes, + times: usize, + a: usize, + b: usize, + c: usize, +) {} +``` + +### Usage + +Here is a program to test your function: + +```rust +fn main() { + println!( + "Does 100 rectangles (2x1) fit in a 2 by 4 square? {}", + area_fit(2, 4, GeometricalShapes::Rectangle, 100, 2, 1) + ); + println!( + "Does 3 triangles (5 base and 3 height) fit in a 5 by 5 square? {}", + area_fit(5, 5, GeometricalShapes::Triangle, 3, 5, 3) + ); + println!( + "Does 3 spheres (2 radius) fit in a 5 by 5 by 5 box? {}", + volume_fit(5, 5, 5, GeometricalVolumes::Sphere, 3, 2, 0, 0) + ); + println!( + "Does 3 triangles (5 base and 3 height) fit in a 5 by 7 by 5 box? {}", + volume_fit(5, 7, 5, GeometricalVolumes::Parallelepiped, 1, 6, 7, 4) + ); +} +``` + +And its output: + +```sh +$ cargo run +false +true +false +true +$ +``` diff --git a/subjects/expected_variable/README.md b/subjects/expected_variable/README.md new file mode 100644 index 000000000..016aaf918 --- /dev/null +++ b/subjects/expected_variable/README.md @@ -0,0 +1,45 @@ +## expected_variable + +### Instructions + +Create a function `expected_variable` that receives two strings: one to be evaluated and the other to be compared to (expected) and returns an Option. Every comparison should be case insensitive. + +If the evaluated string is not in camel case or in snake case according to the `case` crate that you should use, `expected_variable` returns None. +Otherwise the evaluated string should be compared to the expected string using the `edit_distance` function that you did in one of the previous quests. + +If the result of `edit_distance` has more than 50% of 'alikeness' to the expected string, considering the length of the expected string and the result of `edit_distance`, return that same percentage with a '%' symbol in front of the number. +Otherwise `expected_value` should return None. + +Example: + +```rs +fn main() { + println!( + "{} close to it", + expected_variable("On_Point", "on_point").unwrap() + ); + println!( + "{} close to it", + expected_variable("soClose", "So_Close").unwrap() + ); + println!( + "{} close to it", + expected_variable("something", "something_completely_different").unwrap() + ); + println!( + "{} close to it", + expected_variable("BenedictCumberbatch", "BeneficialCucumbersnatch").unwrap() + ); +} +``` + +And its output: + +```sh +$ cargo run +100% +88% +Fail +73% +$ +``` diff --git a/subjects/macro_calculator/README.md b/subjects/macro_calculator/README.md new file mode 100644 index 000000000..73d9900bf --- /dev/null +++ b/subjects/macro_calculator/README.md @@ -0,0 +1,71 @@ +## macro_calculator + +### Instructions + +Create a function `calculate_macros` that receives a vector of `serde_json::Value` and returns a `serde_json::Value`. + +The vector you will receive will contain jsons in the following format: + +```json +{ + "name": , + "calories": [, ], + "fats": , + "carbs": , + "proteins": , + "nbr_of_portions": +} +``` + +Besides the name and the content of the calories array, that are strings, everything else are floats. + +As the result of the function you should return a json with the following format (Macros struct): + +```json + "cals": , + "carbs": , + "proteins": , + "fats": , +``` + +The number of portions should be taken into account. The values of the macros refer to one portion. +All values should be floats (f64) and should be the addition of every macronutrient in the provided array (cals is the addition of every calories, fats is the addition of every fats, and so on...). +Every value should be rounded to two decimal places (ex: 12.29) or one decimal place if it ends in 0 (ex: 18.90 -> 18.9). + +Hint: You will need the `serde`, `serde_json` and `serde_derive` crates. + +### Example + +```rust +fn main() { + let a = serde_json::json!( + { + "name": "light milk", + "calories": ["148kJ", "35kcal"], + "protein": 3.5, + "fats": 0.1, + "carbs": 5.0, + "nbr_of_portions": 0.7 + }); + + let b = serde_json::json!({ + "name": "oat cookies", + "calories": ["1996kJ", "477kcal"], + "protein": 8.2, + "fats": 21.0, + "carbs": 60.4, + "nbr_of_portions": 1.2, + }); + + let macros: Macros = serde_json::from_value(calculate_macros(vec![a, b])).unwrap(); + println!("{:?}", macros); +} +``` + +And its output: + +```sh +$ cargo run +Macros { cals: 596.9, carbs: 75.98, proteins: 12.29, fats: 25.27 } +$ +``` diff --git a/subjects/middle_day/README.md b/subjects/middle_day/README.md new file mode 100644 index 000000000..d2fb98594 --- /dev/null +++ b/subjects/middle_day/README.md @@ -0,0 +1,22 @@ +## middle_day + +### Instructions + +Use the [`chrono`](https://docs.rs/chrono/0.4.19/chrono/index.html) crate to create a function called `middle_day`, that returns the Weekday of the middle day of the year passed as an argument, wrapped in an Option. +You also should refer to chrono::Weekday as `wd`. + +```rs +fn main() { + let date = Utc.ymd(2011, 12, 2).and_hms(21, 12, 09); + + println!("{:?}", middle_day(1022).unwrap()); +} +``` + +And its output: + +```sh +$ cargo run +Tue +$ +``` diff --git a/subjects/mobs/README.md b/subjects/mobs/README.md new file mode 100644 index 000000000..f350f6f0e --- /dev/null +++ b/subjects/mobs/README.md @@ -0,0 +1,91 @@ +## mobs + +### Instructions + +Create a module `mob`, in which it has to be present: + +- a `Mob` structure that consists of: + - a String `name` + - a Boss struct `boss` + - a vector of Members `members` + - a vector of tuples containing a name String and a value u8 `cities` + - a u32 `wealth` + +The Mob struct should implement the following functions: + +- `recruit`, that adds a member to the members vector of the Mob when receiving a `member_name` (&str) and a `member_age` (u8) (the role should be Associate) +- `attack`, that receives another Mob and will remove the last member from the vector of Members from the Mob with the less power combat (in case of draw, the loser is the attacker). The power combat is calculated by its members: + - an Underboss power combat is 4 + - a Caporegime power combat is 3 + - a Soldier power combat is 2 + - an Associate power combat is 1 + - In case of one of the mobs stays without members, the winner mob adds to its cities every city of the loser mob and the same happens to the wealth, and the loser mob loses all cities and all wealth +- `steal`, that receives the targeted mob (Mob) and a value (u32) and adds to the own mob a value and subtracts the value +- `conquer_city`, that receives a vector of mobs, a city name (String) and a value (u8) and adds it to the vector of cities of the own mob, only if no mob in the vector owns a city with that name + +Also create two submodules of mob: + +- `boss` submodule which should contain: + - a `Boss` struct that consists of: + - a String `name` + - an u8 `age` + - a function `new` that returns a Boss on receiving a name (&str) and an age (u8) +- `member` submodule which consists of: + - a enum `Role` with the variants: + - Underboss + - Caporegime + - Soldier + - Associate + - a `Member` struct that consists of: + - a String name + - a enum Role `role` + - a u8 `age` + - the Member struct should implement a function `get_promotion` which will change the member role. If a member is an Associate, it will get promoted to Soldier; a Soldier is promoted to a Caporegime and a Caporegime is promoted to Underboss + - a function `new` that return a Member on receiving a name(&str), a role (Role) and an age (u8) + +You must include `#[derive(Debug, CLone, PartialEq)]` on top of every struct and the enum. + +### Usage + +Here is a program to test your function: + +```rust +fn main() { + let (mafia1, mafia2) = ( + Mob { + name: "Hairy Giants".to_string(), + boss: boss::new("Louie HaHa", 36), + cities: vec![("San Francisco".to_string(), 7)], + members: vec![ + member::new("Benny Eggs", member::Role::Soldier, 28), + member::new("Jhonny", member::Role::Associate, 17), + member::new("Greasy Thumb", member::Role::Soldier, 30), + member::new("No Finger", member::Role::Caporegime, 32), + ], + wealth: 100000, + }, + Mob { + name: "Red Thorns".to_string(), + boss: boss::new("Big Tuna", 30), + cities: vec![("San Jose".to_string(), 5)], + members: vec![ + member::new("Knuckles", member::Role::Soldier, 25), + member::new("Baldy Dom", member::Role::Caporegime, 36), + member::new("Crazy Joe", member::Role::Underboss, 23), + ], + wealth: 70000, + }, + ); + + println!("{:?}\n{:?}", mafia1, mafia2); +} +``` + +And its output: + +```sh +$ cargo run +Mob { name: "Hairy Giants", boss: Boss { name: "Louie HaHa", age: 36 }, members: [Member { name: "Benny Eggs", role: Soldier, age: 28 }, Member { name: "Jhonny", role: Associate, age: 17 }, Member { name: "Greasy Thumb", role: Soldier, age: 30 }, Member { name: "No Finger", role: Caporegime, age: 32 }], cities: [("San Francisco", 7)], wealth: 100000 } +Mob { name: "Red Thorns", boss: Boss { name: "Big Tuna", age: 30 }, members: [Member { name: "Knuckles", role: Soldier, age: 25 }, Member { name: "Baldy Dom", role: Caporegime, age: 36 }, Member { name: "Crazy Joe", role: Underboss, age: 23 }], cities: [("San Jose", 5)], wealth: 70000 } +$ +``` diff --git a/subjects/shopping_mall/README.md b/subjects/shopping_mall/README.md new file mode 100644 index 000000000..006b78263 --- /dev/null +++ b/subjects/shopping_mall/README.md @@ -0,0 +1,99 @@ +## shopping_mall + +### Instructions + +You will have to create several functions to help run a shopping mall, with the help of the `mall` module provided: + +- `biggest_store`: receives a `mall::Mall` and returns the `Store` with the biggest `square_meters`; +- `highest_paid_employees`: receives a `mall::Mall` and returns a vector containing the `Employee`(s) with the highest salaries; +- `nbr_of_employees`: receives a `mall::Mall` and returns the number of employees and securities, as an `usize`, in that mall. +- `fire_old_securities`: receives a `mall::Mall` and removes from the `mall::Mall.securities` all securities who are 50 years old or older. +- `check_securities`: receives a `mall::Mall` and a vector of `Security` and if there are not at least 1 security for every 200 square meters of floor size, there should be added a security to the `mall::Mall.securities` +- `cut_or_raise`: receives a `mall::Mall and raises or cuts the salary of every employee in the mall by 10% depending if the employee works for more than 10 hours + +### Example + +```rust +fn main() { + let secs = vec![ + mall::security::Security::new("John Oliver", 34, 7), + mall::security::Security::new("Logan West", 23, 2), + mall::security::Security::new("Bob Schumacher", 53, 15), + ]; + + let footzo_emp = vec![ + mall::floor::store::employee::Employee::new("Finbar Haines", 36, 9, 14, 650.88), + mall::floor::store::employee::Employee::new("Roksanna Rocha", 45, 13, 22, 772.00), + mall::floor::store::employee::Employee::new("Sienna-Rose Penn", 26, 9, 22, 1000.43), + ]; + let swashion_emp = vec![ + mall::floor::store::employee::Employee::new("Abdallah Stafford", 54, 8, 22, 1234.21), + mall::floor::store::employee::Employee::new("Marian Snyder", 21, 8, 14, 831.90), + mall::floor::store::employee::Employee::new("Amanda Mclean", 29, 13, 22, 1222.12), + mall::floor::store::employee::Employee::new("Faizaan Castro", 32, 11, 18, 1106.43), + ]; + let pizbite_emp = vec![ + mall::floor::store::employee::Employee::new("Juniper Cannon", 21, 16, 23, 804.35), + mall::floor::store::employee::Employee::new("Alena Simon", 28, 9, 15, 973.54), + mall::floor::store::employee::Employee::new("Yasemin Collins", 29, 9, 19, 986.33), + mall::floor::store::employee::Employee::new("Areeb Roberson", 54, 9, 22, 957.82), + mall::floor::store::employee::Employee::new("Rocco Amin", 44, 13, 23, 689.21), + ]; + let grill_emp = vec![ + mall::floor::store::employee::Employee::new("Rhian Crowther", 45, 9, 15, 841.18), + mall::floor::store::employee::Employee::new("Nikkita Steadman", 52, 14, 22, 858.61), + mall::floor::store::employee::Employee::new("Reginald Poole", 32, 9, 22, 1197.64), + mall::floor::store::employee::Employee::new("Minnie Bull", 54, 14, 22, 1229.73), + ]; + let sumo_emp = vec![ + mall::floor::store::employee::Employee::new("Chantelle Barajas", 20, 8, 22, 969.22), + mall::floor::store::employee::Employee::new("Hywel Rudd", 49, 12, 22, 695.74), + mall::floor::store::employee::Employee::new("Marianne Beasley", 55, 8, 14, 767.83), + ]; + let supermaket_emp = vec![ + mall::floor::store::employee::Employee::new("Amara Schaefer", 23, 9, 14, 796.21), + mall::floor::store::employee::Employee::new("Yara Wickens", 39, 9, 14, 853.42), + mall::floor::store::employee::Employee::new("Tomi Boyer", 64, 9, 14, 881.83), + mall::floor::store::employee::Employee::new("Greta Dickson", 42, 9, 14, 775.10), + mall::floor::store::employee::Employee::new("Caroline Finnegan", 41, 9, 14, 702.92), + mall::floor::store::employee::Employee::new("Indiana Baxter", 33, 13, 20, 991.71), + mall::floor::store::employee::Employee::new("Jadine Page", 48, 13, 20, 743.21), + mall::floor::store::employee::Employee::new("Husna Ryan", 43, 13, 20, 655.75), + mall::floor::store::employee::Employee::new("Tyler Hunt", 63, 13, 20, 668.25), + mall::floor::store::employee::Employee::new("Dahlia Caldwell", 56, 13, 20, 781.38), + mall::floor::store::employee::Employee::new("Chandler Mansell", 20, 19, 24, 656.75), + mall::floor::store::employee::Employee::new("Mohsin Mcgee", 30, 19, 24, 703.83), + mall::floor::store::employee::Employee::new("Antoine Goulding", 45, 19, 24, 697.12), + mall::floor::store::employee::Employee::new("Mark Barnard", 53, 19, 24, 788.81), + ]; + + let ground_stores = vec![ + store::Store::new("Footzo", 50, footzo_emp), + store::Store::new("Swashion", 43, swashion_emp), + ]; + let food_stores = vec![ + store::Store::new("PizBite", 60, pizbite_emp), + store::Store::new("Chillout Grill", 50, grill_emp), + store::Store::new("Sumo Food", 30, sumo_emp), + ]; + let supermarket = vec![store::Store::new("Pretail", 950, supermaket_emp)]; + + let floors = vec![ + floor::Floor::new("Ground Floor", ground_stores, 300), + floor::Floor::new("Food Floor", food_stores, 500), + floor::Floor::new("Supermarket", supermarket, 1000), + ]; + + let mall_la_vie = mall::Mall::new("La Vie Funchal", secs, floors); + + println!("{:?}", &mall_la_vie); +} +``` + +And its ouput: + +```rs +$ cargo run +Mall { name: "La Vie Funchal", securities: [Security { name: "John Oliver", age: 34, years_experience: 7 }, Security { name: "Logan West", age: 23, years_experience: 2 }, Security { name: "Bob Schumacher", age: 53, years_experience: 15 }], floors: [Floor { name: "Ground Floor", stores: [Store { name: "Footzo", square_meters: 50, employees: [Employee { name: "Finbar Haines", age: 36, working_hours: (9, 14), salary: 650.88 }, Employee { name: "Roksanna Rocha", age: 45, working_hours: (13, 22), salary: 772.0 }, Employee { name: "Sienna-Rose Penn", age: 26, working_hours: (9, 22), salary: 1000.43 }] }, Store { name: "Swashion", square_meters: 43, employees: [Employee { name: "Abdallah Stafford", age: 54, working_hours: (8, 22), salary: 1234.21 }, Employee { name: "Marian Snyder", age: 21, working_hours: (8, 14), salary: 831.9 }, Employee { name: "Amanda Mclean", age: 29, working_hours: (13, 22), salary: 1222.12 }, Employee { name: "Faizaan Castro", age: 32, working_hours: (11, 18), salary: 1106.43 }] }], size_limit: 300 }, Floor { name: "Food Floor", stores: [Store { name: "PizBite", square_meters: 60, employees: [Employee { name: "Juniper Cannon", age: 21, working_hours: (16, 23), salary: 804.35 }, Employee { name: "Alena Simon", age: 28, working_hours: (9, 15), salary: 973.54 }, Employee { name: "Yasemin Collins", age: 29, working_hours: (9, 19), salary: 986.33 }, Employee { name: "Areeb Roberson", age: 54, working_hours: (9, 22), salary: 957.82 }, Employee { name: "Rocco Amin", age: 44, working_hours: (13, 23), salary: 689.21 }] }, Store { name: "Chillout Grill", square_meters: 50, employees: [Employee { name: "Rhian Crowther", age: 45, working_hours: (9, 15), salary: 841.18 }, Employee { name: "Nikkita Steadman", age: 52, working_hours: (14, 22), salary: 858.61 }, Employee { name: "Reginald Poole", age: 32, working_hours: (9, 22), salary: 1197.64 }, Employee { name: "Minnie Bull", age: 54, working_hours: (14, 22), salary: 1229.73 }] }, Store { name: "Sumo Food", square_meters: 30, employees: [Employee { name: "Chantelle Barajas", age: 20, working_hours: (8, 22), salary: 969.22 }, Employee { name: "Hywel Rudd", age: 49, working_hours: (12, 22), salary: 695.74 }, Employee { name: "Marianne Beasley", age: 55, working_hours: (8, 14), salary: 767.83 }] }], size_limit: 500 }, Floor { name: "Supermarket", stores: [Store { name: "Pretail", square_meters: 950, employees: [Employee { name: "Amara Schaefer", age: 23, working_hours: (9, 14), salary: 796.21 }, Employee { name: "Yara Wickens", age: 39, working_hours: (9, 14), salary: 853.42 }, Employee { name: "Tomi Boyer", age: 64, working_hours: (9, 14), salary: 881.83 }, Employee { name: "Greta Dickson", age: 42, working_hours: (9, 14), salary: 775.1 }, Employee { name: "Caroline Finnegan", age: 41, working_hours: (9, 14), salary: 702.92 }, Employee { name: "Indiana Baxter", age: 33, working_hours: (13, 20), salary: 991.71 }, Employee { name: "Jadine Page", age: 48, working_hours: (13, 20), salary: 743.21 }, Employee { name: "Husna Ryan", age: 43, working_hours: (13, 20), salary: 655.75 }, Employee { name: "Tyler Hunt", age: 63, working_hours: (13, 20), salary: 668.25 }, Employee { name: "Dahlia Caldwell", age: 56, working_hours: (13, 20), salary: 781.38 }, Employee { name: "Chandler Mansell", age: 20, working_hours: (19, 24), salary: 656.75 }, Employee { name: "Mohsin Mcgee", age: 30, working_hours: (19, 24), salary: 703.83 }, Employee { name: "Antoine Goulding", age: 45, working_hours: (19, 24), salary: 697.12 }, Employee { name: "Mark Barnard", age: 53, working_hours: (19, 24), salary: 788.81 }] }], size_limit: 1000 }] } +$ +```