Exercism track submissions
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Rust track; initial commit

+3506
+2
.gitignore
··· 1 + **/.exercism/metadata.json 2 + **/target
+18
rust/assembly-line/.exercism/config.json
··· 1 + { 2 + "blurb": "Learn about numbers while working on an assembly line for cars.", 3 + "authors": [ 4 + "LewisClement", 5 + "efx" 6 + ], 7 + "files": { 8 + "solution": [ 9 + "src/lib.rs" 10 + ], 11 + "test": [ 12 + "tests/assembly-line.rs" 13 + ], 14 + "exemplar": [ 15 + ".meta/exemplar.rs" 16 + ] 17 + } 18 + }
+7
rust/assembly-line/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "assembly-line" 7 + version = "0.1.0"
+4
rust/assembly-line/Cargo.toml
··· 1 + [package] 2 + name = "assembly-line" 3 + version = "0.1.0" 4 + edition = "2021"
+85
rust/assembly-line/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+13
rust/assembly-line/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + ## 1. Calculate the production rate per hour 6 + 7 + - Determining the success rate can be done through a [conditional statement](https://doc.rust-lang.org/stable/book/ch03-05-control-flow.html#if-expressions) or with [pattern matching](https://doc.rust-lang.org/stable/book/ch18-01-all-the-places-for-patterns.html#match-arms). 8 + - As Rust only allows multiplication between values of the same type, some [type casting](https://doc.rust-lang.org/rust-by-example/types/cast.html) will have to be done. 9 + 10 + ## 2. Calculate the number of working items produced per minute 11 + 12 + 13 + - Just like multiplication, division is only possible between numbers of the same type. By writing a number with a decimal point (e.g. `1.0` instead of `1`) we can write inline constants with a floating point type.
+86
rust/assembly-line/README.md
··· 1 + # Assembly Line 2 + 3 + Welcome to Assembly Line on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + ## numbers 10 + 11 + There are two different categories of numbers in Rust. 12 + 13 + The name of a numeric type consists of two parts: 14 + 15 + - A letter to specify whether it's a floating-point number (f), unsigned integer (u) or signed integer (i) 16 + - A number to specify the type's size in bits. Larger types have a greater range between minimum and maximum values. 17 + For floating points it will also allow for more numbers behind the decimal separator. 18 + 19 + The following combinations are possible: 20 + 21 + - 8 bits: `u8`, `i8` 22 + - 16 bits: `u16`, `i16` 23 + - 32 bits: `u32`, `i32`, `f32` 24 + - 64 bits: `u64`, `i64`, `f64` 25 + - 128 bits: `u128`, `i128` 26 + 27 + Note that there are only 32-bits and 64-bits variants for floating-point numbers. 28 + 29 + ## Integers 30 + 31 + - Integers: numbers with no digits behind the decimal separator (whole numbers). 32 + Integer types can either store only positive numbers (unsigned) or store either positive and negative numbers (signed). 33 + Examples are -6, 0, 1, 25, 976 and 500000. 34 + 35 + ## Floating Point Numbers 36 + 37 + - Floating-point numbers: numbers with zero or more digits behind the decimal separator. 38 + Examples are -2.4, 0.1, 3.14, 16.984025 and 1024.0. 39 + 40 + ## Converting between number types 41 + 42 + Rust doesn't do any implicit type conversion. 43 + This means that if you need to turn one numeric type into another, you have to do so explicitly. 44 + When converting from a larger type to a smaller one (for instance `u64` to `u32`) you could lose data. 45 + Converting from a floating point to an integer **will** lose everything behind the decimal point, effectively rounding down. 46 + 47 + ## Instructions 48 + 49 + In this exercise you'll be writing code to analyze the production of an assembly line in a car factory. The assembly line's speed can range from `0` (off) to `10` (maximum). 50 + 51 + At its lowest speed (`1`), `221` cars are produced each hour. The production increases linearly with the speed. So with the speed set to `4`, it should produce `4 * 221 = 884` cars per hour. However, higher speeds increase the likelihood that faulty cars are produced, which then have to be discarded. The following table shows how speed influences the success rate: 52 + 53 + - `1` to `4`: 100% success rate. 54 + - `5` to `8`: 90% success rate. 55 + - `9` and `10`: 77% success rate. 56 + 57 + You have two tasks. 58 + 59 + ## 1. Calculate the production rate per hour 60 + 61 + Implement a method to calculate the assembly line's production rate per hour, taking into account its success rate: 62 + 63 + ```rust 64 + numbers::production_rate_per_hour(6) 65 + // Returns: 1193.4 66 + ``` 67 + 68 + Note that the value returned is an `f64`. 69 + 70 + ## 2. Calculate the number of working items produced per minute 71 + 72 + Implement a method to calculate how many working cars are produced per minute: 73 + 74 + ```rust 75 + numbers::working_items_per_minute(6) 76 + // Returns: 19 77 + ``` 78 + 79 + Note that the value returned is an `u32`. 80 + 81 + ## Source 82 + 83 + ### Created by 84 + 85 + - @LewisClement 86 + - @efx
+29
rust/assembly-line/src/lib.rs
··· 1 + // This stub file contains items which aren't used yet; feel free to remove this module attribute 2 + // to enable stricter warnings. 3 + #![allow(unused)] 4 + 5 + const LOWEST_PROD_RATE: f64 = 221.00; 6 + 7 + fn success_rate(speed: u8) -> Option<f64> { 8 + match (speed) { 9 + 1..=4 => Some(1_f64), 10 + 5..=8 => Some(0.9), 11 + 9..=10 => Some(0.77), 12 + _ => None, 13 + } 14 + } 15 + 16 + fn ideal_prod_rate(speed: u8) -> f64 { 17 + speed as f64 * LOWEST_PROD_RATE 18 + } 19 + 20 + pub fn production_rate_per_hour(speed: u8) -> f64 { 21 + match (success_rate(speed)) { 22 + Some(succ_rate) => succ_rate * ideal_prod_rate(speed), 23 + None => 0_f64, 24 + } 25 + } 26 + 27 + pub fn working_items_per_minute(speed: u8) -> u32 { 28 + (production_rate_per_hour(speed) / 60_f64) as u32 29 + }
+71
rust/assembly-line/tests/assembly-line.rs
··· 1 + fn process_rate_per_hour(speed: u8, expected_rate: f64) { 2 + let actual_rate = assembly_line::production_rate_per_hour(speed); 3 + let actual_rate = (actual_rate * 100.0).round() / 100.0; 4 + assert!((actual_rate - expected_rate).abs() < f64::EPSILON); 5 + } 6 + 7 + fn process_rate_per_minute(speed: u8, expected_rate: u32) { 8 + assert_eq!( 9 + assembly_line::working_items_per_minute(speed), 10 + expected_rate 11 + ); 12 + } 13 + 14 + #[test] 15 + fn production_rate_per_hour_at_speed_zero() { 16 + process_rate_per_hour(0, 0.0); 17 + } 18 + 19 + #[ignore] 20 + #[test] 21 + fn production_rate_per_hour_at_speed_one() { 22 + process_rate_per_hour(1, 221.0); 23 + } 24 + 25 + #[ignore] 26 + #[test] 27 + fn production_rate_per_hour_at_speed_four() { 28 + process_rate_per_hour(4, 884.0); 29 + } 30 + 31 + #[ignore] 32 + #[test] 33 + fn production_rate_per_hour_at_speed_seven() { 34 + process_rate_per_hour(7, 1392.3); 35 + } 36 + 37 + #[ignore] 38 + #[test] 39 + fn production_rate_per_hour_at_speed_nine() { 40 + process_rate_per_hour(9, 1531.53); 41 + } 42 + 43 + #[ignore] 44 + #[test] 45 + fn production_rate_per_minute_at_speed_zero() { 46 + process_rate_per_minute(0, 0); 47 + } 48 + 49 + #[ignore] 50 + #[test] 51 + fn production_rate_per_minute_at_speed_one() { 52 + process_rate_per_minute(1, 3); 53 + } 54 + 55 + #[ignore] 56 + #[test] 57 + fn production_rate_per_minute_at_speed_five() { 58 + process_rate_per_minute(5, 16); 59 + } 60 + 61 + #[ignore] 62 + #[test] 63 + fn production_rate_per_minute_at_speed_eight() { 64 + process_rate_per_minute(8, 26); 65 + } 66 + 67 + #[ignore] 68 + #[test] 69 + fn production_rate_per_minute_at_speed_ten() { 70 + process_rate_per_minute(10, 28); 71 + }
+17
rust/health-statistics/.exercism/config.json
··· 1 + { 2 + "blurb": "Learn structs to store statistics for a health-monitoring system.", 3 + "authors": [ 4 + "seanchen1991" 5 + ], 6 + "files": { 7 + "solution": [ 8 + "src/lib.rs" 9 + ], 10 + "test": [ 11 + "tests/health-statistics.rs" 12 + ], 13 + "exemplar": [ 14 + ".meta/exemplar.rs" 15 + ] 16 + } 17 + }
+7
rust/health-statistics/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "health_statistics" 7 + version = "0.1.0"
+4
rust/health-statistics/Cargo.toml
··· 1 + [package] 2 + name = "health_statistics" 3 + version = "0.1.0" 4 + edition = "2021"
+85
rust/health-statistics/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+31
rust/health-statistics/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + ## 1. Implement the `new()` method 6 + 7 + - The `new()` method receives the arguments we want to instantiate a `User` instance with. It should return an instance of `User` with the specified name, age, and weight. 8 + 9 + - See [here](https://doc.rust-lang.org/book/ch05-01-defining-structs.html) for additional examples on defining and instantiating structs. 10 + 11 + ## 2. Implement the getter methods 12 + 13 + - The `name()`, `age()`, and `weight()` methods are getters. In other words, they are responsible for returning the corresponding field from a struct instance. 14 + 15 + - Notice that the `name` method returns a `&str` when the `name` field on the `User` struct is a `String`. How can we get `&str` and `String` to play nice with each other? 16 + 17 + - There's no need to use a `return` statement in Rust unless you expressly want a function or method to return early. Otherwise, it's more idiomatic to utilize an _implicit_ return by omitting the semicolon for the result we want a function or method to return. It's not _wrong_ to use an explicit return, but it's cleaner to take advantage of implicit returns where possible. 18 + 19 + ```rust 20 + fn foo() -> i32 { 21 + 1 22 + } 23 + ``` 24 + 25 + - See [here](https://doc.rust-lang.org/book/ch05-03-method-syntax.html) for some more examples of defining methods on structs. 26 + 27 + ## 3. Implement the setter methods 28 + 29 + - The `set_age()` and `set_weight()` methods are setters, responsible for updating the corresponding field on a struct instance with the input argument. 30 + 31 + - As the signatures of these methods specify, the setter methods shouldn't return anything.
+91
rust/health-statistics/README.md
··· 1 + # Health Statistics 2 + 3 + Welcome to Health Statistics on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + It is often useful to group a collection of items together, and handle those groups as units. In Rust, we call such a group a struct, and each item one of the struct's fields. A struct defines the general set of fields available, but a particular example of a struct is called an instance. 10 + 11 + Furthermore, structs can have methods defined on them, which have access to the fields. The struct itself in that case is referred to as `self`. When a method uses `&mut self`, the fields can be changed, or mutated. When a method uses `&self`, the fields cannot be changed: they are immutable. Controlling mutability helps the borrow-checker ensure that entire classes of concurrency bug just don't happen in Rust. 12 + 13 + In this exercise, you'll be implementing two kinds of methods on a struct. The first are generally known as getters: they expose the struct's fields to the world, without letting anyone else mutate that value. In Rust, these methods idiomatically share the name of the field they expose, i.e., if we have a getter method that fetches a struct field called `name`, the method would simply be called `name()`. 14 + 15 + You'll also be implementing methods of another type, generally known as setters. These change the value of the field. Setters aren't very common in Rust--if a field can be freely modified, it is more common to just make it public--but they're useful if updating the field should have side effects, or for access control: a setter marked as `pub(crate)` allows other modules within the same crate to update a private field, which can't be affected by the outside world. 16 + 17 + Structs come in three flavors: structs with named fields, tuple structs, and unit structs. For this concept exercise, we'll be exploring the first variant: structs with named fields. 18 + 19 + Structs are defined using the `struct` keyword, followed by the capitalized name of the type the struct is describing: 20 + 21 + ```rust 22 + struct Item {} 23 + ``` 24 + 25 + Additional types are then brought into the struct body as _fields_ of the struct, each with their own type: 26 + 27 + ```rust 28 + struct Item { 29 + name: String, 30 + weight: f32, 31 + worth: u32, 32 + } 33 + ``` 34 + 35 + Lastly, methods can be defined on structs inside of an `impl` block: 36 + 37 + ```rust 38 + impl Item { 39 + // initializes and returns a new instance of our Item struct 40 + fn new() -> Self { 41 + unimplemented!() 42 + } 43 + } 44 + ``` 45 + 46 + With that brief introduction to the syntax of structs out of the way, go ahead and take a look at the [instructions](instructions.md) for this exercise! 47 + 48 + ## Instructions 49 + 50 + You're working on implementing a health-monitoring system. As part of that, you need to keep track of users' health statistics. 51 + 52 + You'll start with some stubbed functions in an `impl` block as well as the following struct definition: 53 + 54 + ```rust 55 + pub struct User { 56 + name: String, 57 + age: u32, 58 + weight: f32, 59 + } 60 + ``` 61 + 62 + Your goal is to implement the stubbed out methods on the `User` `struct` defined in the `impl` block. 63 + 64 + For example, the `new` method should return an instance of the `User` struct with the specified name, age, and weight values. 65 + 66 + ```rust 67 + let mut bob = User::new(String::from("Bob"), 32, 155.2); 68 + // Returns: a User with name "Bob", age 32, and weight 155.2 69 + ``` 70 + 71 + The `weight` method should return the weight of the `User`. 72 + 73 + ```rust 74 + bob.weight(); 75 + // Returns: 155.2 76 + ``` 77 + 78 + The `set_age` method should set the age of the `User`. 79 + 80 + ```rust 81 + bob.set_age(33); 82 + // Updates Bob's age to 33; happy birthday Bob! 83 + ``` 84 + 85 + Have fun! 86 + 87 + ## Source 88 + 89 + ### Created by 90 + 91 + - @seanchen1991
+35
rust/health-statistics/src/lib.rs
··· 1 + // This stub file contains items which aren't used yet; feel free to remove this module attribute 2 + // to enable stricter warnings. 3 + #![allow(unused)] 4 + 5 + pub struct User { 6 + name: String, 7 + age: u32, 8 + weight: f32, 9 + } 10 + 11 + impl User { 12 + pub fn new(name: String, age: u32, weight: f32) -> Self { 13 + User {name, age, weight} 14 + } 15 + 16 + pub fn name(&self) -> &str { 17 + &self.name 18 + } 19 + 20 + pub fn age(&self) -> u32 { 21 + self.age 22 + } 23 + 24 + pub fn weight(&self) -> f32 { 25 + self.weight 26 + } 27 + 28 + pub fn set_age(&mut self, new_age: u32) { 29 + self.age = new_age 30 + } 31 + 32 + pub fn set_weight(&mut self, new_weight: f32) { 33 + self.weight = new_weight 34 + } 35 + }
+43
rust/health-statistics/tests/health-statistics.rs
··· 1 + use health_statistics::*; 2 + 3 + const NAME: &str = "Ebenezer"; 4 + const AGE: u32 = 89; 5 + const WEIGHT: f32 = 131.6; 6 + 7 + #[test] 8 + fn test_name() { 9 + let user = User::new(NAME.into(), AGE, WEIGHT); 10 + assert_eq!(user.name(), NAME); 11 + } 12 + 13 + #[test] 14 + #[ignore] 15 + fn test_age() { 16 + let user = User::new(NAME.into(), AGE, WEIGHT); 17 + assert_eq!(user.age(), AGE); 18 + } 19 + 20 + #[test] 21 + #[ignore] 22 + fn test_weight() { 23 + let user = User::new(NAME.into(), AGE, WEIGHT); 24 + assert!((user.weight() - WEIGHT).abs() < f32::EPSILON); 25 + } 26 + 27 + #[test] 28 + #[ignore] 29 + fn test_set_age() { 30 + let new_age: u32 = 90; 31 + let mut user = User::new(NAME.into(), AGE, WEIGHT); 32 + user.set_age(new_age); 33 + assert_eq!(user.age(), new_age); 34 + } 35 + 36 + #[test] 37 + #[ignore] 38 + fn test_set_weight() { 39 + let new_weight: f32 = 129.4; 40 + let mut user = User::new(NAME.into(), AGE, WEIGHT); 41 + user.set_weight(new_weight); 42 + assert!((user.weight() - new_weight).abs() < f32::EPSILON); 43 + }
+41
rust/hello-world/.exercism/config.json
··· 1 + { 2 + "blurb": "The classical introductory exercise. Just say \"Hello, World!\"", 3 + "authors": [ 4 + "EduardoBautista" 5 + ], 6 + "contributors": [ 7 + "ashleygwilliams", 8 + "ClashTheBunny", 9 + "coriolinus", 10 + "cwhakes", 11 + "dvoytik", 12 + "EduardoBautista", 13 + "efx", 14 + "ErikSchierboom", 15 + "hydhknn", 16 + "IanWhitney", 17 + "ijanos", 18 + "kytrinyx", 19 + "lutostag", 20 + "nfiles", 21 + "petertseng", 22 + "regnerjr", 23 + "rofrol", 24 + "stringparser", 25 + "xakon", 26 + "ZapAnton" 27 + ], 28 + "files": { 29 + "solution": [ 30 + "src/lib.rs" 31 + ], 32 + "test": [ 33 + "tests/hello-world.rs" 34 + ], 35 + "example": [ 36 + ".meta/example.rs" 37 + ] 38 + }, 39 + "source": "This is an exercise to introduce users to using Exercism", 40 + "source_url": "http://en.wikipedia.org/wiki/%22Hello,_world!%22_program" 41 + }
+8
rust/hello-world/.gitignore
··· 1 + # Generated by Cargo 2 + # will have compiled files and executables 3 + /target/ 4 + **/*.rs.bk 5 + 6 + # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 + # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 8 + Cargo.lock
+4
rust/hello-world/Cargo.toml
··· 1 + [package] 2 + edition = "2021" 3 + name = "hello-world" 4 + version = "1.1.0"
+92
rust/hello-world/GETTING_STARTED.md
··· 1 + # Getting Started 2 + 3 + These exercises lean on Test-Driven Development (TDD), but they're not 4 + an exact match. 5 + 6 + The following steps assume that you are in the same directory as the exercise. 7 + 8 + You must have Rust installed. 9 + Follow the [Installation chapter in the Rust book](https://doc.rust-lang.org/book/ch01-01-installation.html). 10 + The [Rust language section](http://exercism.io/languages/rust) 11 + section from exercism is also useful. 12 + 13 + ## Step 1 14 + 15 + Run the test suite. It can be run with `cargo`, which is installed with Rust. 16 + 17 + ```sh 18 + $ cargo test 19 + ``` 20 + 21 + This will compile the `hello-world` crate and run the test, which fails. 22 + 23 + ```sh 24 + running 1 test 25 + test test_hello_world ... FAILED 26 + 27 + failures: 28 + 29 + ---- test_hello_world stdout ---- 30 + thread 'test_hello_world' panicked at 'assertion failed: `(left == right)` 31 + (left: `"Hello, World!"`, right: `"Goodbye, Mars!"`)', tests/hello-world.rs:5 32 + 33 + failures: 34 + test_hello_world 35 + 36 + test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured 37 + ``` 38 + 39 + ### Understanding Test Failures 40 + 41 + The `test_hello_world` failure states that it is expecting the value, 42 + `"Hello, World!"`, to be returned from `hello()`. 43 + The left side of the assertion (at line 5) should be equal to the right side. 44 + 45 + ```sh 46 + ---- test_hello_world stdout ---- 47 + thread 'test_hello_world' panicked at 'assertion failed: `(left == right)` 48 + (left: `"Hello, World!"`, right: `"Goodbye, Mars!"`)', tests/hello-world.rs:5 49 + ``` 50 + 51 + ### Fixing the Error 52 + 53 + To fix it, open up `src/lib.rs` and change the `hello` function to return 54 + `"Hello, World!"` instead of `"Goodbye, Mars!"`. 55 + 56 + ```rust 57 + pub fn hello() -> &'static str { 58 + "Hello, World!" 59 + } 60 + ``` 61 + 62 + ## Step 2 63 + 64 + Run the test again. This time, it will pass. 65 + 66 + ```sh 67 + running 0 tests 68 + 69 + test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured 70 + 71 + Running target/debug/deps/hello_world-bd1f06dc726ef14f 72 + 73 + running 1 test 74 + test test_hello_world ... ok 75 + 76 + test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured 77 + 78 + Doc-tests hello-world 79 + 80 + running 0 tests 81 + 82 + test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured 83 + ``` 84 + 85 + ## Submit 86 + 87 + Once the test is passing, you can submit your code with the following 88 + command: 89 + 90 + ```sh 91 + $ exercism submit src/lib.rs 92 + ```
+85
rust/hello-world/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+53
rust/hello-world/README.md
··· 1 + # Hello World 2 + 3 + Welcome to Hello World on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + 6 + ## Instructions 7 + 8 + The classical introductory exercise. Just say "Hello, World!". 9 + 10 + ["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is 11 + the traditional first program for beginning programming in a new language 12 + or environment. 13 + 14 + The objectives are simple: 15 + 16 + - Write a function that returns the string "Hello, World!". 17 + - Run the test suite and make sure that it succeeds. 18 + - Submit your solution and check it at the website. 19 + 20 + If everything goes well, you will be ready to fetch your first real exercise. 21 + 22 + ## Source 23 + 24 + ### Created by 25 + 26 + - @EduardoBautista 27 + 28 + ### Contributed to by 29 + 30 + - @ashleygwilliams 31 + - @ClashTheBunny 32 + - @coriolinus 33 + - @cwhakes 34 + - @dvoytik 35 + - @EduardoBautista 36 + - @efx 37 + - @ErikSchierboom 38 + - @hydhknn 39 + - @IanWhitney 40 + - @ijanos 41 + - @kytrinyx 42 + - @lutostag 43 + - @nfiles 44 + - @petertseng 45 + - @regnerjr 46 + - @rofrol 47 + - @stringparser 48 + - @xakon 49 + - @ZapAnton 50 + 51 + ### Based on 52 + 53 + This is an exercise to introduce users to using Exercism - http://en.wikipedia.org/wiki/%22Hello,_world!%22_program
+4
rust/hello-world/src/lib.rs
··· 1 + // &'static is a "lifetime specifier", something you'll learn more about later 2 + pub fn hello() -> &'static str { 3 + "Hello, World!" 4 + }
+4
rust/hello-world/tests/hello-world.rs
··· 1 + #[test] 2 + fn test_hello_world() { 3 + assert_eq!("Hello, World!", hello_world::hello()); 4 + }
+17
rust/low-power-embedded-game/.exercism/config.json
··· 1 + { 2 + "blurb": "Learn tuples while writing convenience functions for a low-power embedded game", 3 + "authors": [ 4 + "coriolinus" 5 + ], 6 + "files": { 7 + "solution": [ 8 + "src/lib.rs" 9 + ], 10 + "test": [ 11 + "tests/low-power-embedded-game.rs" 12 + ], 13 + "exemplar": [ 14 + ".meta/exemplar.rs" 15 + ] 16 + } 17 + }
+7
rust/low-power-embedded-game/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "low_power_embedded_game" 7 + version = "0.1.0"
+4
rust/low-power-embedded-game/Cargo.toml
··· 1 + [package] 2 + name = "low_power_embedded_game" 3 + version = "0.1.0" 4 + edition = "2021"
+85
rust/low-power-embedded-game/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+23
rust/low-power-embedded-game/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + - [Rust Book: The Tuple Type](https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type) 6 + - [Rust By Example: Tuples](https://doc.rust-lang.org/stable/rust-by-example/primitives/tuples.html) 7 + - [Rust By Example: Destructuring](https://doc.rust-lang.org/stable/rust-by-example/flow_control/match/destructuring.html) 8 + 9 + ## 1. Write a function `divmod` which returns both the quotient and remainder of a division 10 + 11 + - Don't worry about optimizing for efficiency; the naive implementation is fine 12 + 13 + ## 2. Write an iterator adaptor `evens` which returns the even items from an arbitrary iterator 14 + 15 + - Just chain together the suggested methods and everything will work out 16 + - A number `n` is even if `n % 2 == 0` 17 + - A closure is a function with abbreviated syntax: the argument name(s) go within a pair of `|` symbols, and the expression follows. Unlike normal functions, it is not always necessary to explicitly state the type of each argument, just the name. For example, here is how you can construct an iterator of odd squares: `(0..).map(|n| 2 * n + 1).map(|n| n * n)`. 18 + 19 + ## 3. Implement a `manhattan` method on a `Position` tuple struct 20 + 21 + - Don't worry about method syntax; just replacing the `unimplemented` portion within the `impl Position` block will do the right thing. 22 + - Consider that some values within a `Position` may be negative, but a distance is never negative. 23 + - Calculating the absolute value is [built-in](https://doc.rust-lang.org/std/primitive.i16.html#method.abs)
+162
rust/low-power-embedded-game/README.md
··· 1 + # Low-Power Embedded Game 2 + 3 + Welcome to Low-Power Embedded Game on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + Tuples are a lightweight way to group a fixed set of arbitrary types of data together. A tuple doesn't have 10 + a particular name; naming a data structure turns it into a `struct`. A tuple's fields don't have names; 11 + they are accessed by means of destructuring or by position. 12 + 13 + ## Syntax 14 + 15 + ### Creation 16 + 17 + Tuples are always created with a tuple expression: 18 + 19 + ```rust 20 + // pointless but legal 21 + let unit = (); 22 + // single element 23 + let single_element = ("note the comma",); 24 + // two element 25 + let two_element = (123, "elements can be of differing types"); 26 + ``` 27 + 28 + Tuples can have an arbitrary number of elements. 29 + 30 + ### Access by destructuring 31 + 32 + It is possible to access the elements of a tuple by destructuring. This just means assigning variable 33 + names to the individual elements of the tuple, consuming it. 34 + 35 + ```rust 36 + let (elem1, _elem2) = two_element; 37 + assert_eq!(elem1, 123); 38 + ``` 39 + 40 + ### Access by position 41 + 42 + It is also possible to access the elements of a tuple by numeric positional index. Indexing, as always, 43 + begins at 0. 44 + 45 + ```rust 46 + let notation = single_element.0; 47 + assert_eq!(notation, "note the comma"); 48 + ``` 49 + 50 + ## Tuple Structs 51 + 52 + You will also be asked to work with tuple structs. Like normal structs, these are named types; unlike 53 + normal structs, they have anonymous fields. Their syntax is very similar to normal tuple syntax. It is 54 + legal to use both destructuring and positional access. 55 + 56 + ```rust 57 + struct TupleStruct(u8, i32); 58 + let my_tuple_struct = TupleStruct(123, -321); 59 + let neg = my_tuple_struct.1; 60 + let TupleStruct(byte, _) = my_tuple_struct; 61 + assert_eq!(neg, -321); 62 + assert_eq!(byte, 123); 63 + ``` 64 + 65 + ### Field Visibility 66 + 67 + All fields of anonymous tuples are always public. However, fields of tuple structs have individual 68 + visibility which defaults to private, just like fields of standard structs. You can make the fields 69 + public with the `pub` modifier, just as in a standard struct. 70 + 71 + ```rust 72 + // fails due to private fields 73 + mod tuple { pub struct TupleStruct(u8, i32); } 74 + fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); } 75 + ``` 76 + 77 + ```rust 78 + // succeeds: fields are public 79 + mod tuple { pub struct TupleStruct(pub u8, pub i32); } 80 + fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); } 81 + ``` 82 + 83 + ## Instructions 84 + 85 + You are working on a game targeting a low-power embedded system and need to write several convenience functions which will be used by other parts of the game. 86 + 87 + ## 1. Calculate the quotient and remainder of a division 88 + 89 + A quotient is the output of a division. 90 + 91 + ```rust 92 + fn divmod(dividend: i16, divisor: i16) -> (i16, i16) 93 + ``` 94 + 95 + Example: 96 + 97 + ```rust 98 + assert_eq!(divmod(10, 3), (3, 1)); 99 + ``` 100 + 101 + ## 2. Choose even-positioned items from an iterator 102 + 103 + This will be helpful to enable a screen-buffer optimization, your boss promises. 104 + 105 + Iterators are items which expose the methods defined by the [`Iterator` trait](https://doc.rust-lang.org/std/iter/trait.Iterator.html). That documentation is fairly extensive, because they offer many methods; here are the most relevant properties: 106 + 107 + - An iterator is an arbitrary-length stream of items 108 + - They have an [`enumerate` method](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.enumerate) which returns a tuple `(i, val)` for each value 109 + - They have a [`filter` method](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter) which uses a closure to determine whether to yield an element of the iterator 110 + - They have a [`map` method](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map) which uses a closure to modify elements of the iterator 111 + 112 + Because your function can run on any kind of iterator, it uses `impl` to signify that this is a trait instance instead of a simple item. Likewise, the `<Item=T>` syntax just means that it doesn't matter what kind of item the iterator produces; your function can produce the even elements of any iterator. 113 + 114 + ```rust 115 + fn evens<T>(iter: impl Iterator<Item=T>) -> impl Iterator<Item=T> 116 + ``` 117 + 118 + Examples: 119 + 120 + ```rust 121 + let mut even_ints = evens(0_u8..); 122 + assert_eq!(even_ints.next(), Some(0)); 123 + assert_eq!(even_ints.next(), Some(2)); 124 + assert_eq!(even_ints.next(), Some(4)); 125 + assert_eq!(even_ints.next(), Some(6)); 126 + ``` 127 + 128 + ```rust 129 + let mut evens_from_odds = evens(1_i16..); 130 + assert_eq!(evens_from_odds.next(), Some(1)); 131 + assert_eq!(evens_from_odds.next(), Some(3)); 132 + assert_eq!(evens_from_odds.next(), Some(5)); 133 + assert_eq!(evens_from_odds.next(), Some(7)); 134 + ``` 135 + 136 + ## 3. Calculate the manhattan distance of a position from the origin 137 + 138 + For mapping convenience, you have a tuple struct `Position`: 139 + 140 + ```rust 141 + struct Position(i16, i16); 142 + ``` 143 + 144 + You need to implement a method `manhattan` on `Position` which returns the [manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry) of that position from the origin (`Position(0, 0)`). 145 + 146 + ```rust 147 + impl Position { 148 + fn manhattan(&self) -> i16 149 + } 150 + ``` 151 + 152 + Example: 153 + 154 + ```rust 155 + assert_eq!(Position(3, 4).manhattan(), 7); 156 + ``` 157 + 158 + ## Source 159 + 160 + ### Created by 161 + 162 + - @coriolinus
+19
rust/low-power-embedded-game/src/lib.rs
··· 1 + // This stub file contains items which aren't used yet; feel free to remove this module attribute 2 + // to enable stricter warnings. 3 + #![allow(unused)] 4 + 5 + pub fn divmod(dividend: i16, divisor: i16) -> (i16, i16) { 6 + (dividend / divisor, dividend % divisor) 7 + } 8 + 9 + pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T> { 10 + iter.enumerate() 11 + .filter_map(|(i, x)| if i % 2 == 0 { Some(x) } else { None }) 12 + } 13 + 14 + pub struct Position(pub i16, pub i16); 15 + impl Position { 16 + pub fn manhattan(&self) -> i16 { 17 + self.0.abs() + self.1.abs() 18 + } 19 + }
+110
rust/low-power-embedded-game/tests/low-power-embedded-game.rs
··· 1 + mod divmod { 2 + //! tests of divmod 3 + //! 4 + //! note that we're only testing positive quantities; no need to get into the mod/rem distinction 5 + 6 + use low_power_embedded_game::divmod; 7 + 8 + #[test] 9 + fn example() { 10 + assert_eq!(divmod(10, 3), (3, 1)); 11 + } 12 + 13 + #[test] 14 + #[ignore] 15 + fn powerup() { 16 + assert_eq!(divmod(100, 3), (33, 1)); 17 + } 18 + 19 + #[test] 20 + #[ignore] 21 + fn less() { 22 + assert_eq!(divmod(3, 10), (0, 3)); 23 + } 24 + 25 + #[test] 26 + #[ignore] 27 + fn eq() { 28 + assert_eq!(divmod(3, 3), (1, 0)); 29 + } 30 + 31 + #[test] 32 + #[ignore] 33 + fn multiple() { 34 + assert_eq!(divmod(9, 3), (3, 0)); 35 + } 36 + } 37 + 38 + mod evens { 39 + use low_power_embedded_game::evens; 40 + 41 + #[test] 42 + #[ignore] 43 + fn simple_i32() { 44 + let out: Vec<i32> = evens(0..).take(5).collect(); 45 + assert_eq!(out, &[0, 2, 4, 6, 8]); 46 + } 47 + 48 + #[test] 49 + #[ignore] 50 + fn reverse_i32() { 51 + let out: Vec<i32> = evens((0..=10).rev()).collect(); 52 + assert_eq!(out, &[10, 8, 6, 4, 2, 0]); 53 + } 54 + 55 + #[test] 56 + #[ignore] 57 + fn offset_i32() { 58 + let out: Vec<i32> = evens(1..).take(5).collect(); 59 + assert_eq!(out, &[1, 3, 5, 7, 9]); 60 + } 61 + 62 + #[test] 63 + #[ignore] 64 + fn strs() { 65 + let input = "You really must never be above joking.".split_whitespace(); 66 + let expected: Vec<_> = "You must be joking.".split_whitespace().collect(); 67 + let out: Vec<_> = evens(input).collect(); 68 + assert_eq!(out, expected); 69 + } 70 + } 71 + 72 + mod manhattan { 73 + use low_power_embedded_game::Position; 74 + 75 + #[test] 76 + #[ignore] 77 + fn origin() { 78 + assert_eq!(Position(0, 0).manhattan(), 0); 79 + } 80 + 81 + #[test] 82 + #[ignore] 83 + fn q1_unit() { 84 + assert_eq!(Position(1, 1).manhattan(), 2); 85 + } 86 + 87 + #[test] 88 + #[ignore] 89 + fn q2_unit() { 90 + assert_eq!(Position(1, -1).manhattan(), 2); 91 + } 92 + 93 + #[test] 94 + #[ignore] 95 + fn q3_unit() { 96 + assert_eq!(Position(-1, -1).manhattan(), 2); 97 + } 98 + 99 + #[test] 100 + #[ignore] 101 + fn q4_unit() { 102 + assert_eq!(Position(-1, 1).manhattan(), 2); 103 + } 104 + 105 + #[test] 106 + #[ignore] 107 + fn relative_prime() { 108 + assert_eq!(Position(30, 70).manhattan(), 100); 109 + } 110 + }
+19
rust/lucians-luscious-lasagna/.exercism/config.json
··· 1 + { 2 + "blurb": "Learn about the basics of Rust by following a lasagna recipe.", 3 + "icon": "lasagna", 4 + "authors": [ 5 + "coriolinus", 6 + "ErikSchierboom" 7 + ], 8 + "files": { 9 + "solution": [ 10 + "src/lib.rs" 11 + ], 12 + "test": [ 13 + "tests/lucians-luscious-lasagna.rs" 14 + ], 15 + "exemplar": [ 16 + ".meta/exemplar.rs" 17 + ] 18 + } 19 + }
+7
rust/lucians-luscious-lasagna/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "lucians-luscious-lasagna" 7 + version = "0.1.0"
+4
rust/lucians-luscious-lasagna/Cargo.toml
··· 1 + [package] 2 + name = "lucians-luscious-lasagna" 3 + version = "0.1.0" 4 + edition = "2021"
+85
rust/lucians-luscious-lasagna/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+31
rust/lucians-luscious-lasagna/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + - An integer literal can be defined as one or more consecutive digits. 6 + 7 + ## 1. Define the expected oven time in minutes 8 + 9 + - You need to define a [function][functions] without any parameters. 10 + 11 + ## 2. Calculate the remaining oven time in minutes 12 + 13 + - You need to define a [function][functions] with a single parameter. 14 + - You can use and refer to the previously defined item by its name. 15 + - The last expression in a function is [automatically returned][return-values] from the function; you don't have to explicitly indicate which value to return. 16 + - You can use the [mathematical operator for subtraction][operators] to subtract values. 17 + 18 + ## 3. Calculate the preparation time in minutes 19 + 20 + - You need to define a [function][functions] with a single parameter. 21 + - You can use the [mathematical operator for multiplicaton][operators] to multiply values. 22 + 23 + ## 4. Calculate the elapsed time in minutes 24 + 25 + - You need to define a [function][functions] with two parameters. 26 + - You can [call][functions] one of the other functions you've defined previously. 27 + - You can use the [mathematical operator for addition][operators] to add values. 28 + 29 + [functions]: https://doc.rust-lang.org/book/ch03-03-how-functions-work.html 30 + [return-values]: https://doc.rust-lang.org/book/ch03-03-how-functions-work.html#functions-with-return-values 31 + [operators]: https://doc.rust-lang.org/book/appendix-02-operators.html
+159
rust/lucians-luscious-lasagna/README.md
··· 1 + # Lucian's Luscious Lasagna 2 + 3 + Welcome to Lucian's Luscious Lasagna on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + In Rust, assigning a value to a name is referred to as a _binding_. Bindings are immutable unless declared with the `mut` keyword. As Rust is a statically-typed language, each binding has a type known at compile-time. 10 + 11 + Bindings are most commonly defined using the `let` keyword. Specifying a binding's type is optional for most bindings, as Rust's _type inference_ can usually infer the type based on their value. A binding looks like this: 12 + 13 + ```rust 14 + // Automatically inferred type 15 + let fingers = 10; 16 + ``` 17 + 18 + Functions are _items_. Where bindings typically refer to a particular value, items refer to a unit of code organization, typically a function or a module, which is available throughout the lifetime of the program. A function automatically returns the result of its last expression. A function may have 0 or more parameters, which are bindings with a lifetime of the function call. 19 + 20 + Type inference is theoretically possible for functions, but is disabled as an intentional language design choice. While this means that you need to spend a little more time when writing code to specify precisely what a function's input and output types are, you save the time when you're reading the code, because all the input and output types are explicitly defined. 21 + 22 + ```rust 23 + fn add(x: i32, y: i32) -> i32 { 24 + x + y 25 + } 26 + ``` 27 + 28 + Invoking a function is done by specifying its name followed by parentheses. If the function requires parameters, an argument must be specified for each within the parentheses. 29 + 30 + ```rust 31 + let five = add(2, 3); 32 + ``` 33 + 34 + If a binding's type cannot be inferred, the compiler will report an error. To fix this, add an explicit type annotation to the binding. 35 + 36 + ```rust 37 + // Explicit type annotation 38 + let fingers: i32 = 10; 39 + ``` 40 + 41 + Items in Rust can be used before or after they are defined, because they have a static lifetime. Bindings, on the other hand, can only be used _after_ they have been defined. Using a binding before it has been defined results in a compile error. 42 + 43 + ```rust 44 + fn main() { 45 + // `fn add` hasn't yet been defined, but that's perfectly ok 46 + dbg!(add(3, 4)); 47 + } 48 + 49 + fn add(x: i32, y: i32) -> i32 { 50 + x + y 51 + } 52 + ``` 53 + 54 + ```rust 55 + // this won't compile; `a` is used before its binding is defined 56 + let b = a; 57 + let a = x + y 58 + ``` 59 + 60 + Rust uses curly braces (`{}`) to define a scope. A binding defined within a scope can't escape from it. 61 + 62 + ```rust 63 + let a = 1; 64 + dbg!(a); // 1 65 + { 66 + // Here, we re-bind `a` to a new value, which is still immutable. 67 + // This technique is called _shadowing_. The new binding is constrained to 68 + // this anonymous scope. Outside this scope, the previous binding still 69 + // applies. 70 + let a = 2; 71 + let b = 3; 72 + dbg!(a, b); // 2, 3 73 + } 74 + // can't use `b` anymore because it is out of scope 75 + // dbg!(b); 76 + 77 + // The shadowed `a` in the inner scope above has fallen out of scope, 78 + // leaving us with our original binding. 79 + dbg!(a); // 1 80 + ``` 81 + 82 + Rust items are often organized in modules. Each crate is implicitly a module, but it can define inner sub-modules of arbitrary depth. A module groups related functionality and is defined using the `mod` keyword. 83 + 84 + ```rust 85 + mod calc_i32 { 86 + fn add(a: i32, b: i32) -> i32 { a + b } 87 + fn sub(a: i32, b: i32) -> i32 { a - b } 88 + fn mul(a: i32, b: i32) -> i32 { a * b } 89 + fn div(a: i32, b: i32) -> i32 { a / b } 90 + } 91 + ``` 92 + 93 + Rust supports two types of comments. The keyword `//` indicates a single-line comment; everything following the keyword until the end of the line is ignored. The keywords `/*` and `*/` indicate a multi-line comment; everything within those two keywords is ignored. It is idiomatic and good practice to prefer single-line comments. 94 + 95 + Rust also supports doc-comments, which show up in the generated documentation produced by `cargo doc`. Outer doc comments are formed with the keyword `///`, which acts identically to the `//` keyword. They apply to the item which follows them, such as a function: 96 + 97 + ```rust 98 + /// The `add` function produces the sum of its arguments. 99 + fn add(x: i32, y: i32) -> i32 { x + y } 100 + ``` 101 + 102 + Inner doc comments are formed with the keyword `//!`, which acts identically to the `//` keyword. They apply to the item enclosing them, such as a module: 103 + 104 + ```rust 105 + mod my_cool_module { 106 + //! This module is the bee's knees. 107 + } 108 + ``` 109 + 110 + Doc comments can be of arbitrary length and contain markdown, which is rendered into the generated documentation. 111 + 112 + ## Instructions 113 + 114 + In this exercise you're going to write some code to help you cook a brilliant lasagna from your favorite cooking book. 115 + 116 + You have four tasks, all related to the time spent cooking the lasagna. 117 + 118 + ## 1. Define the expected oven time in minutes 119 + 120 + Define the `expected_minutes_in_oven` binding to check how many minutes the lasagna should be in the oven. According to the cooking book, the expected oven time in minutes is 40: 121 + 122 + ```rust 123 + expected_minutes_in_oven() 124 + // Returns: 40 125 + ``` 126 + 127 + ## 2. Calculate the remaining oven time in minutes 128 + 129 + Define the `remaining_minutes_in_oven` function that takes the actual minutes the lasagna has been in the oven as a parameter and returns how many minutes the lasagna still has to remain in the oven, based on the expected oven time in minutes from the previous task. 130 + 131 + ```rust 132 + remaining_minutes_in_oven(30) 133 + // Returns: 10 134 + ``` 135 + 136 + ## 3. Calculate the preparation time in minutes 137 + 138 + Define the `preparation_time_in_minutes` function that takes the number of layers you added to the lasagna as a parameter and returns how many minutes you spent preparing the lasagna, assuming each layer takes you 2 minutes to prepare. 139 + 140 + ```rust 141 + preparation_time_in_minutes(2) 142 + // Returns: 4 143 + ``` 144 + 145 + ## 4. Calculate the elapsed time in minutes 146 + 147 + Define the `elapsed_time_in_minutes` function that takes two parameters: the first parameter is the number of layers you added to the lasagna, and the second parameter is the number of minutes the lasagna has been in the oven. The function should return how many minutes you've worked on cooking the lasagna, which is the sum of the preparation time in minutes, and the time in minutes the lasagna has spent in the oven at the moment. 148 + 149 + ```rust 150 + elapsed_time_in_minutes(3, 20) 151 + // Returns: 26 152 + ``` 153 + 154 + ## Source 155 + 156 + ### Created by 157 + 158 + - @coriolinus 159 + - @ErikSchierboom
+20
rust/lucians-luscious-lasagna/src/lib.rs
··· 1 + // This stub file contains items which aren't used yet; feel free to remove this module attribute 2 + // to enable stricter warnings. 3 + #![allow(unused)] 4 + 5 + pub fn expected_minutes_in_oven() -> i32 { 6 + 40 7 + } 8 + 9 + pub fn remaining_minutes_in_oven(actual_minutes_in_oven: i32) -> i32 { 10 + expected_minutes_in_oven() - actual_minutes_in_oven 11 + } 12 + 13 + pub fn preparation_time_in_minutes(number_of_layers: i32) -> i32 { 14 + const LAYER_PREP_TIME: i32 = 2; 15 + number_of_layers * LAYER_PREP_TIME 16 + } 17 + 18 + pub fn elapsed_time_in_minutes(number_of_layers: i32, actual_minutes_in_oven: i32) -> i32 { 19 + preparation_time_in_minutes(number_of_layers) + actual_minutes_in_oven 20 + }
+34
rust/lucians-luscious-lasagna/tests/lucians-luscious-lasagna.rs
··· 1 + use lucians_luscious_lasagna::{ 2 + elapsed_time_in_minutes, expected_minutes_in_oven, preparation_time_in_minutes, 3 + remaining_minutes_in_oven, 4 + }; 5 + 6 + #[test] 7 + fn expected_minutes_in_oven_is_correct() { 8 + assert_eq!(40, expected_minutes_in_oven()); 9 + } 10 + 11 + #[test] 12 + fn remaining_minutes_in_oven_after_fifteen_minutes() { 13 + assert_eq!(15, remaining_minutes_in_oven(25)); 14 + } 15 + 16 + #[test] 17 + fn preparation_time_in_minutes_for_one_layer() { 18 + assert_eq!(2, preparation_time_in_minutes(1)); 19 + } 20 + 21 + #[test] 22 + fn preparation_time_in_minutes_for_multiple_layers() { 23 + assert_eq!(8, preparation_time_in_minutes(4)); 24 + } 25 + 26 + #[test] 27 + fn elapsed_time_in_minutes_for_one_layer() { 28 + assert_eq!(32, elapsed_time_in_minutes(1, 30)); 29 + } 30 + 31 + #[test] 32 + fn elapsed_time_in_minutes_for_multiple_layers() { 33 + assert_eq!(16, elapsed_time_in_minutes(4, 8)); 34 + }
+17
rust/magazine-cutout/.exercism/config.json
··· 1 + { 2 + "blurb": "Use `HashMap` and the entry API methods to write an anonymous letter.", 3 + "authors": [ 4 + "seanchen1991" 5 + ], 6 + "files": { 7 + "solution": [ 8 + "src/lib.rs" 9 + ], 10 + "test": [ 11 + "tests/magazine-cutout.rs" 12 + ], 13 + "exemplar": [ 14 + ".meta/exemplar.rs" 15 + ] 16 + } 17 + }
+7
rust/magazine-cutout/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "magazine_cutout" 7 + version = "0.1.0"
+4
rust/magazine-cutout/Cargo.toml
··· 1 + [package] 2 + name = "magazine_cutout" 3 + version = "0.1.0" 4 + edition = "2021"
+85
rust/magazine-cutout/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+17
rust/magazine-cutout/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + - Upon fetching an entry using the `entry` method, the entry can be modified in-place after dereferencing it. 6 + 7 + - The `or_insert` [method](https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_insert) inserts the given value in the case when the entry is vacant, and returns a mutable reference to the value in the entry. 8 + 9 + ```rust 10 + *counter.entry(key).or_insert(0) += 1; 11 + ``` 12 + 13 + - The `or_default` [method](https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_default) ensures a value is in the entry by inserting the default value if empty, and returns a mutable reference to the value in the entry. 14 + 15 + ```rust 16 + *counter.entry(key).or_default() += 1; 17 + ```
+44
rust/magazine-cutout/README.md
··· 1 + # Magazine Cutout 2 + 3 + Welcome to Magazine Cutout on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + Rust's entry API provides a view into a single entry in map, which may be either a `HashMap` or a `BTreeMap`. The entry may be either occupied and vacant, and the API provides methods to modify the contents of the entry. 10 + 11 + ## Instructions 12 + 13 + In this exercise you'll be using a `HashMap`, along with entry API methods, to solve a simple algorithm problem. 14 + 15 + Given `&[&str]` representing the words of a magazine article, and `&[&str]` representing the words of a note you would like to send, can you compose your note by cutting words out of the magazine and pasting them into a letter? 16 + 17 + Notes: 18 + 19 + - This implies physical cutting and pasting; the magazine needs to contain at least as many copies of each word as the note requires. 20 + - Capitalization matters; just because you're pasting together a note composed from words of a magazine doesn't mean you're willing to be ungrammatical. 21 + 22 + You'll start with the following stubbed function signature: 23 + 24 + ```rust 25 + pub fn can_construct_note(magazine: &[&str], note: &[&str]) -> bool { 26 + unimplemented!() 27 + } 28 + ``` 29 + 30 + Given the following input 31 + 32 + ```rust 33 + let magazine = "two times three is not four".split_whitespace().collect::<Vec<&str>>(); 34 + let note = "two times two is four".split_whitespace().collect::<Vec<&str>>(); 35 + assert!(!can_construct_note(&magazine, &note)); 36 + ``` 37 + 38 + The function returns `false` since the magazine only contains one instance of `"two"` when the note requires two of them. 39 + 40 + ## Source 41 + 42 + ### Created by 43 + 44 + - @seanchen1991
+42
rust/magazine-cutout/src/lib.rs
··· 1 + // This stub file contains items which aren't used yet; feel free to remove this module attribute 2 + // to enable stricter warnings. 3 + #![allow(unused)] 4 + 5 + use std::collections::HashMap; 6 + 7 + type Count = u8; 8 + 9 + #[derive(Eq, PartialEq, Debug)] 10 + struct MyHash<'a>(HashMap<&'a str, Count>); 11 + 12 + impl<'a> MyHash<'a> { 13 + fn from(h: HashMap<&'a str, Count>) -> Self { 14 + MyHash(h) 15 + } 16 + } 17 + 18 + fn parse_text<'a>(xs: &[&'a str]) -> MyHash<'a> { 19 + MyHash::from(xs.iter().zip(std::iter::repeat(1).take(xs.len())).fold( 20 + HashMap::new(), 21 + |mut m, (k, v)| { 22 + m.entry(k).and_modify(|e| *e += 1).or_insert(v); 23 + m 24 + }, 25 + )) 26 + } 27 + 28 + impl<'a> PartialOrd for MyHash<'a> { 29 + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { 30 + match other.0.iter().find(|(x, c)| match self.0.get(**x) { 31 + Some(d) => d < c, 32 + _ => true, 33 + }) { 34 + Some(_) => Some(std::cmp::Ordering::Less), 35 + _ => Some(std::cmp::Ordering::Greater), 36 + } 37 + } 38 + } 39 + 40 + pub fn can_construct_note(magazine: &[&str], note: &[&str]) -> bool { 41 + parse_text(magazine) >= parse_text(note) 42 + }
+67
rust/magazine-cutout/tests/magazine-cutout.rs
··· 1 + use magazine_cutout::*; 2 + 3 + #[test] 4 + fn test_example_works() { 5 + let magazine = "two times three is not four" 6 + .split_whitespace() 7 + .collect::<Vec<&str>>(); 8 + let note = "two times two is four" 9 + .split_whitespace() 10 + .collect::<Vec<&str>>(); 11 + assert!(!can_construct_note(&magazine, &note)); 12 + } 13 + 14 + #[test] 15 + fn test_fn_returns_true_for_good_input() { 16 + let magazine = "The metro orchestra unveiled its new grand piano today. Its donor paraphrased Nathn Hale: \"I only regret that I have but one to give \"".split_whitespace().collect::<Vec<&str>>(); 17 + let note = "give one grand today." 18 + .split_whitespace() 19 + .collect::<Vec<&str>>(); 20 + assert!(can_construct_note(&magazine, &note)); 21 + } 22 + 23 + #[test] 24 + fn test_fn_returns_false_for_bad_input() { 25 + let magazine = "I've got a lovely bunch of coconuts." 26 + .split_whitespace() 27 + .collect::<Vec<&str>>(); 28 + let note = "I've got som coconuts" 29 + .split_whitespace() 30 + .collect::<Vec<&str>>(); 31 + assert!(!can_construct_note(&magazine, &note)); 32 + } 33 + 34 + #[test] 35 + fn test_case_sensitivity() { 36 + let magazine = "i've got some lovely coconuts" 37 + .split_whitespace() 38 + .collect::<Vec<&str>>(); 39 + let note = "I've got some coconuts" 40 + .split_whitespace() 41 + .collect::<Vec<&str>>(); 42 + assert!(!can_construct_note(&magazine, &note)); 43 + 44 + let magazine = "I've got some lovely coconuts" 45 + .split_whitespace() 46 + .collect::<Vec<&str>>(); 47 + let note = "i've got some coconuts" 48 + .split_whitespace() 49 + .collect::<Vec<&str>>(); 50 + assert!(!can_construct_note(&magazine, &note)); 51 + } 52 + 53 + #[test] 54 + fn test_magzine_has_more_than_words_available_than_needed() { 55 + let magazine = "Enough is enough when enough is enough" 56 + .split_whitespace() 57 + .collect::<Vec<&str>>(); 58 + let note = "enough is enough".split_whitespace().collect::<Vec<&str>>(); 59 + assert!(can_construct_note(&magazine, &note)); 60 + } 61 + 62 + #[test] 63 + fn test_magazine_has_one_good_word_many_times_but_still_cant_construct() { 64 + let magazine = "A A A".split_whitespace().collect::<Vec<&str>>(); 65 + let note = "A nice day".split_whitespace().collect::<Vec<&str>>(); 66 + assert!(!can_construct_note(&magazine, &note)); 67 + }
+21
rust/resistor-color/.exercism/config.json
··· 1 + { 2 + "blurb": "Convert a resistor band's color to its numeric representation and back, using external crates", 3 + "authors": [ 4 + "still-flow", 5 + "coriolinus" 6 + ], 7 + "contributors": [], 8 + "files": { 9 + "solution": [ 10 + "src/lib.rs" 11 + ], 12 + "test": [ 13 + "tests/resistor-color.rs" 14 + ], 15 + "exemplar": [ 16 + ".meta/exemplar.rs" 17 + ] 18 + }, 19 + "source": "Maud de Vries, Erik Schierboom", 20 + "source_url": "https://github.com/exercism/problem-specifications/issues/1458" 21 + }
+8
rust/resistor-color/.gitignore
··· 1 + # Generated by Cargo 2 + # will have compiled files and executables 3 + /target/ 4 + **/*.rs.bk 5 + 6 + # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 + # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 8 + Cargo.lock
+8
rust/resistor-color/Cargo.toml
··· 1 + [package] 2 + edition = "2021" 3 + name = "resistor-color" 4 + version = "1.0.0" 5 + 6 + [dependencies] 7 + int-enum = "0.4.0" 8 + enum-iterator = "0.7.0"
+85
rust/resistor-color/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+11
rust/resistor-color/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + - Use the `enum-iterator` crate to be able to iterate over enums. Check out [docs](https://docs.rs/enum-iterator/0.7.0/enum_iterator/) to find out how. 6 + 7 + - Use the `int-enum` crate to be able to convert from int to enum. See the [docs](https://docs.rs/int-enum/0.4.0/int_enum/) for details. 8 + 9 + - The `Debug` trait is there because you'll likely need it. 10 + 11 + - You'll need to extend the list of `derive`d traits on your colors enum.
+65
rust/resistor-color/README.md
··· 1 + # Resistor Color 2 + 3 + Welcome to Resistor Color on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + Most programs have dependencies on some libraries. Managing those by hand can be a pain. Luckily, the Rust ecosystem comes standard with `cargo`! `cargo` can manage dependencies for a project. 10 + 11 + You will often see external packages being referred to as "crates" in Rust. A crate is a compilation unit in Rust. A crate can be compiled into a binary or into a library. 12 + 13 + Most of the time, adding an external dependency is as simple as adding a line to your `Cargo.toml` file. 14 + 15 + In this exercise, [`enum-iterator`](https://docs.rs/enum-iterator/0.7.0/enum_iterator/) and [`int-enum`](https://docs.rs/int-enum/0.4.0/int_enum/) dependencies were added for you. 16 + 17 + ## Instructions 18 + 19 + If you want to build something using a Raspberry Pi, you'll probably use _resistors_. 20 + For this exercise, you need to know two things about them: 21 + 22 + - Each resistor has a resistance value. 23 + - Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read. 24 + 25 + To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. 26 + Each band has a position and a numeric value. 27 + 28 + The first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number. 29 + 30 + In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. 31 + 32 + These colors are encoded as follows: 33 + 34 + - Black: 0 35 + - Brown: 1 36 + - Red: 2 37 + - Orange: 3 38 + - Yellow: 4 39 + - Green: 5 40 + - Blue: 6 41 + - Violet: 7 42 + - Grey: 8 43 + - White: 9 44 + 45 + The goal of this exercise is to create a way: 46 + - to look up the numerical value associated with a particular color band 47 + - to convert the numerical value into a string representing color 48 + - to list the different band colors 49 + 50 + For tasks number two and three, you will need external crates [`enum-iterator`](https://docs.rs/enum-iterator/0.7.0/enum_iterator/) and [`int-enum`](https://docs.rs/int-enum/0.4.0/int_enum/), which are included in this exercise's `Cargo.toml`. Be sure to check the crates' documentation to learn how to use them. 51 + 52 + Mnemonics map the colors to the numbers, that, when stored as an array, happen to map to their index in the array: Better Be Right Or Your Great Big Values Go Wrong. 53 + 54 + More information on the color encoding of resistors can be found in the [Electronic color code Wikipedia article](https://en.wikipedia.org/wiki/Electronic_color_code) 55 + 56 + ## Source 57 + 58 + ### Created by 59 + 60 + - @still-flow 61 + - @coriolinus 62 + 63 + ### Based on 64 + 65 + Maud de Vries, Erik Schierboom - https://github.com/exercism/problem-specifications/issues/1458
+34
rust/resistor-color/src/lib.rs
··· 1 + 2 + use int_enum::IntEnum; 3 + use enum_iterator::IntoEnumIterator; 4 + 5 + #[repr(usize)] 6 + #[derive(Clone, Copy, Debug, PartialEq, IntEnum, IntoEnumIterator)] 7 + pub enum ResistorColor { 8 + Black = 0, 9 + Brown = 1, 10 + Red = 2, 11 + Orange = 3, 12 + Yellow = 4, 13 + Green = 5, 14 + Blue = 6, 15 + Violet = 7, 16 + Grey = 8, 17 + White = 9, 18 + } 19 + 20 + pub fn color_to_value(color: ResistorColor) -> usize { 21 + color.int_value() 22 + } 23 + 24 + pub fn value_to_color_string(value: usize) -> String { 25 + let x = ResistorColor::from_int(value); 26 + match x{ 27 + Ok(v) => format!("{:?}", v), 28 + Err(_) => "value out of range".to_string() 29 + } 30 + } 31 + 32 + pub fn colors() -> Vec<ResistorColor> { 33 + ResistorColor::into_enum_iter().collect() 34 + }
+55
rust/resistor-color/tests/resistor-color.rs
··· 1 + use resistor_color::{color_to_value, colors, value_to_color_string, ResistorColor}; 2 + 3 + #[test] 4 + fn test_black() { 5 + assert_eq!(color_to_value(ResistorColor::Black), 0); 6 + } 7 + 8 + #[test] 9 + #[ignore] 10 + fn test_orange() { 11 + assert_eq!(color_to_value(ResistorColor::Orange), 3); 12 + } 13 + 14 + #[test] 15 + #[ignore] 16 + fn test_white() { 17 + assert_eq!(color_to_value(ResistorColor::White), 9); 18 + } 19 + 20 + #[test] 21 + #[ignore] 22 + fn test_2() { 23 + assert_eq!(value_to_color_string(2), String::from("Red")); 24 + } 25 + 26 + #[test] 27 + #[ignore] 28 + fn test_6() { 29 + assert_eq!(value_to_color_string(6), String::from("Blue")); 30 + } 31 + 32 + #[test] 33 + #[ignore] 34 + fn test_8() { 35 + assert_eq!(value_to_color_string(8), String::from("Grey")); 36 + } 37 + 38 + #[test] 39 + #[ignore] 40 + fn test_11_out_of_range() { 41 + assert_eq!( 42 + value_to_color_string(11), 43 + String::from("value out of range") 44 + ); 45 + } 46 + 47 + #[test] 48 + #[ignore] 49 + fn test_all_colors() { 50 + use ResistorColor::*; 51 + assert_eq!( 52 + colors(), 53 + vec![Black, Brown, Red, Orange, Yellow, Green, Blue, Violet, Grey, White] 54 + ); 55 + }
+18
rust/role-playing-game/.exercism/config.json
··· 1 + { 2 + "blurb": "Learn about the `Option` enum by creating a minimal role-playing game", 3 + "authors": [ 4 + "seanchen1991", 5 + "coriolinus" 6 + ], 7 + "files": { 8 + "solution": [ 9 + "src/lib.rs" 10 + ], 11 + "test": [ 12 + "tests/role-playing-game.rs" 13 + ], 14 + "exemplar": [ 15 + ".meta/exemplar.rs" 16 + ] 17 + } 18 + }
+7
rust/role-playing-game/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "role_playing_game" 7 + version = "0.1.0"
+4
rust/role-playing-game/Cargo.toml
··· 1 + [package] 2 + name = "role_playing_game" 3 + version = "0.1.0" 4 + edition = "2021"
+85
rust/role-playing-game/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+1
rust/role-playing-game/HINTS.md
··· 1 + # Hints
+79
rust/role-playing-game/README.md
··· 1 + # Role-Playing Game 2 + 3 + Welcome to Role-Playing Game on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + ## Instructions 10 + 11 + You're working on implementing a role-playing game. The player's character is represented by the following: 12 + 13 + ```rust 14 + pub struct Player { 15 + health: u32, 16 + mana: Option<u32>, 17 + level: u32, 18 + } 19 + ``` 20 + 21 + Players in this game must reach level 10 before they unlock a mana pool so that they can start casting spells. Before that point, the Player's mana is `None`. 22 + 23 + You're working on two pieces of functionality in this game, the revive mechanic and the spell casting mechanic. 24 + 25 + The `revive` method should check to ensure that the Player is indeed dead (their health has reached 0), and if they are, the method should return a new Player instance with 100 health. 26 + If the Player's level is 10 or above, they should also be revived with 100 mana. 27 + If the Player's level is below 10, their mana should be `None`. The `revive` method should preserve the Player's level. 28 + 29 + ```rust 30 + let dead_player = Player { health: 0, mana: None, level: 2 }; 31 + dead_player.revive() 32 + // Returns Player { health: 100, mana: None, level: 2 } 33 + ``` 34 + 35 + If the `revive` method is called on a Player whose health is 1 or above, then the method should return `None`. 36 + 37 + ```rust 38 + let alive_player = Player { health: 1, mana: Some(15), level: 11 }; 39 + alive_player.revive() 40 + // Returns None 41 + ``` 42 + 43 + The `cast_spell` method takes a mutable reference to the Player as well as a `mana_cost` parameter indicating how much mana the spell costs. It returns the amount of damage that the cast spell performs, which will always be two times the mana cost of the spell if the spell is successfully cast. 44 + 45 + - If the player does not have access to a mana pool, attempting to cast the spell must decrease their health by the mana cost of the spell. The damage returned must be 0. 46 + 47 + ```rust 48 + let not_a_wizard_yet = Player { health: 79, mana: None, level: 9 }; 49 + assert_eq!(not_a_wizard_yet.cast_spell(5), 0) 50 + assert_eq!(not_a_wizard_yet.health, 74); 51 + assert_eq!(not_a_wizard_yet.mana, None); 52 + ``` 53 + 54 + - If the player has a mana pool but insufficient mana, the method should not affect the pool, but instead return 0 55 + 56 + ```rust 57 + let low_mana_wizard = Player { health: 93, mana: Some(3), level: 12 }; 58 + assert_eq!(low_mana_wizard.cast_spell(10), 0); 59 + assert_eq!(low_mana_wizard.health, 93); 60 + assert_eq!(low_mana_wizard.mana, Some(3)); 61 + ``` 62 + 63 + - Otherwise, the `mana_cost` should be deducted from the Player's mana pool and the appropriate amount of damage should be returned. 64 + 65 + ```rust 66 + let wizard = Player { health: 123, mana: Some(30), level: 18 }; 67 + assert_eq!(wizard.cast_spell(10), 20); 68 + assert_eq!(wizard.health, 123); 69 + assert_eq!(wizard.mana, Some(20)); 70 + ``` 71 + 72 + Have fun! 73 + 74 + ## Source 75 + 76 + ### Created by 77 + 78 + - @seanchen1991 79 + - @coriolinus
+47
rust/role-playing-game/src/lib.rs
··· 1 + // This stub file contains items which aren't used yet; feel free to remove this module attribute 2 + // to enable stricter warnings. 3 + #![allow(unused)] 4 + 5 + pub struct Player { 6 + pub health: u32, 7 + pub mana: Option<u32>, 8 + pub level: u32, 9 + } 10 + 11 + impl Player { 12 + pub fn new(health: u32, mana: u32, level: u32) -> Self { 13 + Player { 14 + health, 15 + mana: if level < 10 { None } else { Some(mana) }, 16 + level, 17 + } 18 + } 19 + 20 + pub fn revive(&self) -> Option<Player> { 21 + match self.health { 22 + 0 => Some(Player::new(100, 100, self.level)), 23 + _ => None, 24 + } 25 + } 26 + 27 + pub fn cast_spell(&mut self, mana_cost: u32) -> u32 { 28 + match self.mana { 29 + None => { 30 + self.health = if self.health > mana_cost { 31 + self.health - mana_cost 32 + } else { 33 + 0 34 + }; 35 + 0 36 + } 37 + Some(x) => { 38 + if x >= mana_cost { 39 + self.mana = Some(x - mana_cost); 40 + mana_cost * 2 41 + } else { 42 + 0 43 + } 44 + } 45 + } 46 + } 47 + }
+136
rust/role-playing-game/tests/role-playing-game.rs
··· 1 + use role_playing_game::*; 2 + 3 + #[test] 4 + fn test_reviving_dead_player() { 5 + let dead_player = Player { 6 + health: 0, 7 + mana: Some(0), 8 + level: 34, 9 + }; 10 + let revived_player = dead_player 11 + .revive() 12 + .expect("reviving a dead player must return Some(player)"); 13 + assert_eq!(revived_player.health, 100); 14 + assert_eq!(revived_player.mana, Some(100)); 15 + assert_eq!(revived_player.level, dead_player.level); 16 + } 17 + 18 + #[test] 19 + #[ignore] 20 + fn test_reviving_dead_level9_player() { 21 + let dead_player = Player { 22 + health: 0, 23 + mana: None, 24 + level: 9, 25 + }; 26 + let revived_player = dead_player 27 + .revive() 28 + .expect("reviving a dead player must return Some(player)"); 29 + assert_eq!(revived_player.health, 100); 30 + assert_eq!(revived_player.mana, None); 31 + assert_eq!(revived_player.level, dead_player.level); 32 + } 33 + 34 + #[test] 35 + #[ignore] 36 + fn test_reviving_dead_level10_player() { 37 + let dead_player = Player { 38 + health: 0, 39 + mana: Some(0), 40 + level: 10, 41 + }; 42 + let revived_player = dead_player 43 + .revive() 44 + .expect("reviving a dead player must return Some(player)"); 45 + assert_eq!(revived_player.health, 100); 46 + assert_eq!(revived_player.mana, Some(100)); 47 + assert_eq!(revived_player.level, dead_player.level); 48 + } 49 + 50 + #[test] 51 + #[ignore] 52 + fn test_reviving_alive_player() { 53 + let alive_player = Player { 54 + health: 1, 55 + mana: None, 56 + level: 8, 57 + }; 58 + assert!(alive_player.revive().is_none()); 59 + } 60 + 61 + #[test] 62 + #[ignore] 63 + fn test_cast_spell_with_enough_mana() { 64 + const HEALTH: u32 = 99; 65 + const MANA: u32 = 100; 66 + const LEVEL: u32 = 100; 67 + const MANA_COST: u32 = 3; 68 + 69 + let mut accomplished_wizard = Player { 70 + health: HEALTH, 71 + mana: Some(MANA), 72 + level: LEVEL, 73 + }; 74 + 75 + assert_eq!(accomplished_wizard.cast_spell(MANA_COST), MANA_COST * 2); 76 + assert_eq!(accomplished_wizard.health, HEALTH); 77 + assert_eq!(accomplished_wizard.mana, Some(MANA - MANA_COST)); 78 + assert_eq!(accomplished_wizard.level, LEVEL); 79 + } 80 + 81 + #[test] 82 + #[ignore] 83 + fn test_cast_spell_with_insufficient_mana() { 84 + let mut no_mana_wizard = Player { 85 + health: 56, 86 + mana: Some(2), 87 + level: 22, 88 + }; 89 + 90 + // we want to clone so we can compare before-and-after effects of casting the spell, 91 + // but we don't want to introduce that concept to the student yet, so we have to do it manually 92 + let clone = Player { ..no_mana_wizard }; 93 + 94 + assert_eq!(no_mana_wizard.cast_spell(3), 0); 95 + assert_eq!(no_mana_wizard.health, clone.health); 96 + assert_eq!(no_mana_wizard.mana, clone.mana); 97 + assert_eq!(no_mana_wizard.level, clone.level); 98 + } 99 + 100 + #[test] 101 + #[ignore] 102 + fn test_cast_spell_with_no_mana_pool() { 103 + const MANA_COST: u32 = 10; 104 + 105 + let mut underleveled_player = Player { 106 + health: 87, 107 + mana: None, 108 + level: 6, 109 + }; 110 + 111 + let clone = Player { 112 + ..underleveled_player 113 + }; 114 + 115 + assert_eq!(underleveled_player.cast_spell(MANA_COST), 0); 116 + assert_eq!(underleveled_player.health, clone.health - MANA_COST); 117 + assert_eq!(underleveled_player.mana, clone.mana); 118 + assert_eq!(underleveled_player.level, clone.level); 119 + } 120 + 121 + #[test] 122 + #[ignore] 123 + fn test_cast_large_spell_with_no_mana_pool() { 124 + const MANA_COST: u32 = 30; 125 + 126 + let mut underleveled_player = Player { 127 + health: 20, 128 + mana: None, 129 + level: 6, 130 + }; 131 + 132 + assert_eq!(underleveled_player.cast_spell(MANA_COST), 0); 133 + assert_eq!(underleveled_player.health, 0); 134 + assert_eq!(underleveled_player.mana, None); 135 + assert_eq!(underleveled_player.level, 6); 136 + }
+17
rust/rpn-calculator/.exercism/config.json
··· 1 + { 2 + "blurb": "Use some of `Vec`'s methods to evaluate Reverse Polish notation", 3 + "authors": [ 4 + "cwhakes" 5 + ], 6 + "files": { 7 + "solution": [ 8 + "src/lib.rs" 9 + ], 10 + "test": [ 11 + "tests/rpn-calculator.rs" 12 + ], 13 + "exemplar": [ 14 + ".meta/exemplar.rs" 15 + ] 16 + } 17 + }
+4
rust/rpn-calculator/Cargo.toml
··· 1 + [package] 2 + name = "rpn_calculator" 3 + version = "0.1.0" 4 + edition = "2021"
+85
rust/rpn-calculator/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+5
rust/rpn-calculator/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + - Look at the documentation for `std::vec::Vec`'s [`push()`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.push) and ['pop()`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pop) methods.
+147
rust/rpn-calculator/README.md
··· 1 + # RPN Calculator 2 + 3 + Welcome to RPN Calculator on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + [Stacks](https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29) are a type of collection commonly used in computer science. 10 + They are defined by their two key operations: **push** and **pop**. 11 + **Push** adds an element to the top of the stack. 12 + **Pop** removes and returns the topmost element. 13 + 14 + Think of a stack like a stack of plates. 15 + You can either add a plate to the top of the stack or take the topmost plate. 16 + To access something further down, you have to remove all of the plates above it. 17 + 18 + Rust's vector implementation, [`std::vec::Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html), can be used as a stack by using its `push()` and `pop()` methods. 19 + Naturally, `push()` adds an element to the end of the `Vec` and `pop()` removes and returns the last element. 20 + These operation can be very fast (O(1) in [Big O Notation](https://en.wikipedia.org/wiki/Big_O_notation)), 21 + so they are one of the most idiomatic ways to use a `Vec`. 22 + 23 + Stacks are useful to hold arbitrary numbers of elements in a specific order. 24 + Because the last element inserted is the first element returned, 25 + stacks are commonly refered to as **LIFO** (Last-In, First-Out). 26 + This inherent ordering can be used for many things, 27 + including tracking state when evaulating **Reverse Polish notation**. 28 + 29 + ## Instructions 30 + 31 + ## 1. Overview 32 + 33 + [Reverse Polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation) (RPN) is a way of writing mathematical expressions. 34 + Unlike in traditional infix notation, RPN operators *follow* their operands. 35 + For example, instead of writing: 36 + 37 + ``` 38 + 2 + 2 39 + ``` 40 + 41 + you would write: 42 + 43 + ``` 44 + 2 2 + 45 + ``` 46 + 47 + The major benefit of Reverse Polish notation is that it is much simpler to parse than infix notation. 48 + RPN eliminates the need for order of operations or parentheses in complex expressions. 49 + For example: 50 + 51 + ``` 52 + (4 + 8) / (7 - 5) 53 + ``` 54 + 55 + can be written as 56 + 57 + ``` 58 + 4 8 + 7 5 - / 59 + ``` 60 + 61 + In both cases, the expression evaluates to 6. 62 + 63 + ## 2. Example 64 + 65 + Lets manually evaluate that complex expression. 66 + As we learned in the introduction, evaluation of RPN requires a stack. 67 + This stack is used to hold numeric values that the operators operate on. 68 + We start our calculator with an empty stack and then evaluate each element one at a time. 69 + 70 + First, we encounter a `4`, 71 + so we push it onto our freshly created stack. 72 + 73 + ``` 74 + 4 75 + ``` 76 + 77 + Next, we encounter an `8`. 78 + We also push that onto the stack. 79 + 80 + ``` 81 + 4 8 82 + ``` 83 + 84 + Now, we encounter a `+`. 85 + We pop off the two topmost values (4 and 8), 86 + add them together, 87 + and push the sum back onto the stack. 88 + 89 + ``` 90 + 12 91 + ``` 92 + 93 + We do something similar for `7`, `5`, and `-`: 94 + 95 + ``` 96 + 12 7 97 + 12 7 5 98 + 12 2 99 + ``` 100 + 101 + Now we encounter a `/`. 102 + Even though we last encountered a `-`, 103 + there are two elements on the stack. 104 + We pop off the two elements, 105 + divide them, 106 + and push the result back onto the stack. 107 + 108 + ``` 109 + 6 110 + ``` 111 + 112 + Finally, since there is exactly one element on the stack, 113 + we can say the expression evaluated to 6. 114 + 115 + ## 3. Goal 116 + 117 + Your goal is to write a calculator to evaluate a list of inputs ordered by Reverse Polish notation and return the final element on the stack. 118 + 119 + If there is not exactly one element in the stack at the end, return `None`. 120 + 121 + If there is an operator with too few operands (such as the input `2 +`), return `None`. 122 + 123 + You are given the following enum and stubbed function as a starting point. 124 + 125 + ```rust 126 + #[derive(Debug)] 127 + pub enum CalculatorInput { 128 + Add, 129 + Subtract, 130 + Multiply, 131 + Divide, 132 + Value(i32), 133 + } 134 + 135 + pub fn evaluate(inputs: &[CalculatorInput]) -> Option<i32> { 136 + unimplemented!( 137 + "Given the inputs: {:?}, evaluate them as though they were a Reverse Polish notation expression", 138 + inputs, 139 + ); 140 + } 141 + ``` 142 + 143 + ## Source 144 + 145 + ### Created by 146 + 147 + - @cwhakes
+15
rust/rpn-calculator/src/lib.rs
··· 1 + #[derive(Debug)] 2 + pub enum CalculatorInput { 3 + Add, 4 + Subtract, 5 + Multiply, 6 + Divide, 7 + Value(i32), 8 + } 9 + 10 + pub fn evaluate(inputs: &[CalculatorInput]) -> Option<i32> { 11 + unimplemented!( 12 + "Given the inputs: {:?}, evaluate them as though they were a Reverse Polish notation expression", 13 + inputs, 14 + ); 15 + }
+89
rust/rpn-calculator/tests/rpn-calculator.rs
··· 1 + use rpn_calculator::*; 2 + 3 + fn calculator_input(s: &str) -> Vec<CalculatorInput> { 4 + s.split_whitespace() 5 + .map(|s| match s { 6 + "+" => CalculatorInput::Add, 7 + "-" => CalculatorInput::Subtract, 8 + "*" => CalculatorInput::Multiply, 9 + "/" => CalculatorInput::Divide, 10 + n => CalculatorInput::Value(n.parse().unwrap()), 11 + }) 12 + .collect() 13 + } 14 + 15 + #[test] 16 + fn test_empty_input_returns_none() { 17 + let input = calculator_input(""); 18 + assert_eq!(evaluate(&input), None); 19 + } 20 + 21 + #[test] 22 + #[ignore] 23 + fn test_simple_value() { 24 + let input = calculator_input("10"); 25 + assert_eq!(evaluate(&input), Some(10)); 26 + } 27 + 28 + #[test] 29 + #[ignore] 30 + fn test_simple_addition() { 31 + let input = calculator_input("2 2 +"); 32 + assert_eq!(evaluate(&input), Some(4)); 33 + } 34 + 35 + #[test] 36 + #[ignore] 37 + fn test_simple_subtraction() { 38 + let input = calculator_input("7 11 -"); 39 + assert_eq!(evaluate(&input), Some(-4)); 40 + } 41 + 42 + #[test] 43 + #[ignore] 44 + fn test_simple_multiplication() { 45 + let input = calculator_input("6 9 *"); 46 + assert_eq!(evaluate(&input), Some(54)); 47 + } 48 + 49 + #[test] 50 + #[ignore] 51 + fn test_simple_division() { 52 + let input = calculator_input("57 19 /"); 53 + assert_eq!(evaluate(&input), Some(3)); 54 + } 55 + 56 + #[test] 57 + #[ignore] 58 + fn test_complex_operation() { 59 + let input = calculator_input("4 8 + 7 5 - /"); 60 + assert_eq!(evaluate(&input), Some(6)); 61 + } 62 + 63 + #[test] 64 + #[ignore] 65 + fn test_too_few_operands_returns_none() { 66 + let input = calculator_input("2 +"); 67 + assert_eq!(evaluate(&input), None); 68 + } 69 + 70 + #[test] 71 + #[ignore] 72 + fn test_too_many_operands_returns_none() { 73 + let input = calculator_input("2 2"); 74 + assert_eq!(evaluate(&input), None); 75 + } 76 + 77 + #[test] 78 + #[ignore] 79 + fn test_zero_operands_returns_none() { 80 + let input = calculator_input("+"); 81 + assert_eq!(evaluate(&input), None); 82 + } 83 + 84 + #[test] 85 + #[ignore] 86 + fn test_intermediate_error_returns_none() { 87 + let input = calculator_input("+ 2 2 *"); 88 + assert_eq!(evaluate(&input), None); 89 + }
+17
rust/semi-structured-logs/.exercism/config.json
··· 1 + { 2 + "blurb": "Learn enums while building a logging utility.", 3 + "authors": [ 4 + "efx" 5 + ], 6 + "files": { 7 + "solution": [ 8 + "src/lib.rs" 9 + ], 10 + "test": [ 11 + "tests/semi-structured-logs.rs" 12 + ], 13 + "exemplar": [ 14 + ".meta/exemplar.rs" 15 + ] 16 + } 17 + }
+7
rust/semi-structured-logs/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "semi_structured_logs" 7 + version = "0.1.0"
+9
rust/semi-structured-logs/Cargo.toml
··· 1 + [package] 2 + name = "semi_structured_logs" 3 + version = "0.1.0" 4 + edition = "2021" 5 + 6 + [features] 7 + add-a-variant = [] 8 + 9 + [dependencies]
+85
rust/semi-structured-logs/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+13
rust/semi-structured-logs/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + - [Rust By Example - Enums][rbe-enums] 6 + - [cheats.rs - Basic Types][cheats-types] 7 + 8 + ## 1. Emit semi-structured messages 9 + 10 + - `match` comes in handy when working with enums. In this case, see how you might use it when figuring how what kind of log message to generate. 11 + 12 + [rbe-enums]: https://doc.rust-lang.org/stable/rust-by-example/custom_types/enum.html#enums 13 + [cheats-types]: https://cheats.rs/#basic-types
+64
rust/semi-structured-logs/README.md
··· 1 + # Semi Structured Logs 2 + 3 + Welcome to Semi Structured Logs on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + Enums, short for enumerations, are a type that limits all possible values of some data. The possible values of an `enum` are called variants. Enums also work well with `match` and other control flow operators to help you express intent in your Rust programs. 10 + 11 + ## Instructions 12 + 13 + In this exercise you'll be generating semi-structured log messages. 14 + 15 + ## 1. Emit semi-structured messages 16 + 17 + You'll start with some stubbed functions and the following enum: 18 + 19 + ```rust 20 + #[derive(Clone, PartialEq, Debug)] 21 + pub enum LogLevel { 22 + Info, 23 + Warning, 24 + Error, 25 + } 26 + ``` 27 + 28 + Your goal is to emit a log message as follows: `"[<LEVEL>]: <MESSAGE>"`. 29 + You'll need to implement functions that correspond with log levels. 30 + 31 + For example, the below snippet demonstrates an expected output for the `log` function. 32 + 33 + ```rust 34 + log(LogLevel::Error, "Stack overflow") 35 + // Returns: "[ERROR]: Stack overflow" 36 + ``` 37 + 38 + And for `info`: 39 + 40 + ```rust 41 + info("Timezone changed") 42 + // Returns: "[INFO]: Timezone changed" 43 + ``` 44 + 45 + Have fun! 46 + 47 + ## 2. Optional further practice 48 + 49 + There is a feature-gated test in this suite. 50 + Feature gates disable compilation entirely for certain sections of your program. 51 + They will be covered later. 52 + For now just know that there is a test which is only built and run when you use a special testing invocation: 53 + 54 + ```sh 55 + cargo test --features add-a-variant 56 + ``` 57 + 58 + This test is meant to show you how to add a variant to your enum. 59 + 60 + ## Source 61 + 62 + ### Created by 63 + 64 + - @efx
+33
rust/semi-structured-logs/src/lib.rs
··· 1 + // This stub file contains items which aren't used yet; feel free to remove this module attribute 2 + // to enable stricter warnings. 3 + 4 + /// various log levels 5 + #[derive(Clone, PartialEq, Debug)] 6 + pub enum LogLevel { 7 + Info, 8 + Warning, 9 + Error, 10 + Debug, 11 + } 12 + 13 + /// primary function for emitting logs 14 + pub fn log(level: LogLevel, message: &str) -> String { 15 + let level_str: String = format!("{:?}", level); 16 + format!( 17 + "[{}]: {}", 18 + level_str.to_uppercase(), 19 + message 20 + ) 21 + } 22 + pub fn info(message: &str) -> String { 23 + log(LogLevel::Info, message) 24 + } 25 + pub fn warn(message: &str) -> String { 26 + log(LogLevel::Warning, message) 27 + } 28 + pub fn error(message: &str) -> String { 29 + log(LogLevel::Error, message) 30 + } 31 + pub fn debug(message: &str) -> String { 32 + log(LogLevel::Debug, message) 33 + }
+53
rust/semi-structured-logs/tests/semi-structured-logs.rs
··· 1 + use semi_structured_logs::{error, info, log, warn, LogLevel}; 2 + 3 + #[test] 4 + fn emits_info() { 5 + assert_eq!(info("Timezone changed"), "[INFO]: Timezone changed"); 6 + } 7 + 8 + #[test] 9 + #[ignore] 10 + fn emits_warning() { 11 + assert_eq!(warn("Timezone not set"), "[WARNING]: Timezone not set"); 12 + } 13 + 14 + #[test] 15 + #[ignore] 16 + fn emits_error() { 17 + assert_eq!(error("Disk full"), "[ERROR]: Disk full"); 18 + } 19 + 20 + #[test] 21 + #[ignore] 22 + fn log_emits_info() { 23 + assert_eq!( 24 + log(LogLevel::Info, "Timezone changed"), 25 + "[INFO]: Timezone changed" 26 + ); 27 + } 28 + 29 + #[test] 30 + #[ignore] 31 + fn log_emits_warning() { 32 + assert_eq!( 33 + log(LogLevel::Warning, "Timezone not set"), 34 + "[WARNING]: Timezone not set" 35 + ); 36 + } 37 + 38 + #[test] 39 + #[ignore] 40 + fn log_emits_error() { 41 + assert_eq!(log(LogLevel::Error, "Disk full"), "[ERROR]: Disk full"); 42 + } 43 + 44 + #[test] 45 + #[cfg(feature = "add-a-variant")] 46 + #[ignore] 47 + fn add_a_variant() { 48 + // this test won't even compile until the enum is complete, which is why it is feature-gated. 49 + assert_eq!( 50 + log(LogLevel::Debug, "reached line 123"), 51 + "[DEBUG]: reached line 123", 52 + ); 53 + }
+18
rust/short-fibonacci/.exercism/config.json
··· 1 + { 2 + "blurb": "Learn the `vec!` macro to build a short Fibonacci Sequence.", 3 + "authors": [ 4 + "efx", 5 + "coriolinus" 6 + ], 7 + "files": { 8 + "solution": [ 9 + "src/lib.rs" 10 + ], 11 + "test": [ 12 + "tests/short-fibonacci.rs" 13 + ], 14 + "exemplar": [ 15 + ".meta/exemplar.rs" 16 + ] 17 + } 18 + }
+8
rust/short-fibonacci/.gitignore
··· 1 + # Generated by Cargo 2 + # will have compiled files and executables 3 + /target/ 4 + **/*.rs.bk 5 + 6 + # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 + # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 8 + Cargo.lock
+4
rust/short-fibonacci/Cargo.toml
··· 1 + [package] 2 + name = "short_fibonacci" 3 + version = "0.1.0" 4 + edition = "2021"
+85
rust/short-fibonacci/HELP.md
··· 1 + # Help 2 + 3 + ## Running the tests 4 + 5 + Execute the tests with: 6 + 7 + ```bash 8 + $ cargo test 9 + ``` 10 + 11 + All but the first test have been ignored. After you get the first test to 12 + pass, open the tests source file which is located in the `tests` directory 13 + and remove the `#[ignore]` flag from the next test and get the tests to pass 14 + again. Each separate test is a function with `#[test]` flag above it. 15 + Continue, until you pass every test. 16 + 17 + If you wish to run _only ignored_ tests without editing the tests source file, use: 18 + 19 + ```bash 20 + $ cargo test -- --ignored 21 + ``` 22 + 23 + If you are using Rust 1.51 or later, you can run _all_ tests with 24 + 25 + ```bash 26 + $ cargo test -- --include-ignored 27 + ``` 28 + 29 + To run a specific test, for example `some_test`, you can use: 30 + 31 + ```bash 32 + $ cargo test some_test 33 + ``` 34 + 35 + If the specific test is ignored, use: 36 + 37 + ```bash 38 + $ cargo test some_test -- --ignored 39 + ``` 40 + 41 + To learn more about Rust tests refer to the online [test documentation][rust-tests]. 42 + 43 + [rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html 44 + 45 + ## Submitting your solution 46 + 47 + You can submit your solution using the `exercism submit src/lib.rs` command. 48 + This command will upload your solution to the Exercism website and print the solution page's URL. 49 + 50 + It's possible to submit an incomplete solution which allows you to: 51 + 52 + - See how others have completed the exercise 53 + - Request help from a mentor 54 + 55 + ## Need to get help? 56 + 57 + If you'd like help solving the exercise, check the following pages: 58 + 59 + - The [Rust track's documentation](https://exercism.org/docs/tracks/rust) 60 + - [Exercism's support channel on gitter](https://gitter.im/exercism/support) 61 + - The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) 62 + 63 + Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. 64 + 65 + ## Rust Installation 66 + 67 + Refer to the [exercism help page][help-page] for Rust installation and learning 68 + resources. 69 + 70 + ## Submitting the solution 71 + 72 + Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer. 73 + 74 + ## Feedback, Issues, Pull Requests 75 + 76 + The GitHub [track repository][github] is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help! 77 + 78 + If you want to know more about Exercism, take a look at the [contribution guide]. 79 + 80 + ## Submitting Incomplete Solutions 81 + It's possible to submit an incomplete solution so you can see how others have completed the exercise. 82 + 83 + [help-page]: https://exercism.io/tracks/rust/learning 84 + [github]: https://github.com/exercism/rust 85 + [contribution guide]: https://exercism.io/docs/community/contributors
+5
rust/short-fibonacci/HINTS.md
··· 1 + # Hints 2 + 3 + ## General 4 + 5 + - Check out the Rust documentation on [the `vec!` macro](https://doc.rust-lang.org/std/macro.vec.html).
+40
rust/short-fibonacci/README.md
··· 1 + # A Short Fibonacci Sequence 2 + 3 + Welcome to A Short Fibonacci Sequence on Exercism's Rust Track. 4 + If you need help running the tests or submitting your code, check out `HELP.md`. 5 + If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) 6 + 7 + ## Introduction 8 + 9 + Rust provides a macro `vec![]` to help you create Vectors. 10 + This comes in quite handy when you need to initialize lists. 11 + 12 + ## Instructions 13 + 14 + You are going to initialize empty buffers and list the first five numbers, or elements, of the Fibonacci sequence. 15 + 16 + The Fibonacci sequence is a set of numbers where the next element is the sum of the prior two. We start the sequence at one. So the first two elements are 1 and 1. 17 + 18 + ## 1. Create a buffer of `count` zeroes. 19 + 20 + Create a function that creates a buffer of `count` zeroes. 21 + ```rust 22 + let my_buffer = create_buffer(5); 23 + // [0, 0, 0, 0, 0] 24 + ``` 25 + 26 + ## 2. List the first five elements of the Fibonacci sequence 27 + 28 + Create a function that returns the first five numbers of the Fibonacci sequence. 29 + Its first five elements are `1, 1, 2, 3, 5` 30 + ```rust 31 + let first_five = fibonacci(); 32 + // [1, 1, 2, 3, 5] 33 + ``` 34 + 35 + ## Source 36 + 37 + ### Created by 38 + 39 + - @efx 40 + - @coriolinus
+25
rust/short-fibonacci/src/lib.rs
··· 1 + /// Create an empty vector 2 + pub fn create_empty() -> Vec<u8> { 3 + vec![] 4 + } 5 + 6 + /// Create a buffer of `count` zeroes. 7 + /// 8 + /// Applications often use buffers when serializing data to send over the network. 9 + pub fn create_buffer(count: usize) -> Vec<u8> { 10 + vec![0; count] 11 + } 12 + 13 + /// Create a vector containing the first five elements of the Fibonacci sequence. 14 + /// 15 + /// Fibonacci's sequence is the list of numbers where the next number is a sum of the previous two. 16 + /// Its first five elements are `1, 1, 2, 3, 5`. 17 + pub fn fibonacci() -> Vec<u8> { 18 + create_buffer(5) 19 + .iter() 20 + .fold((create_empty(), 0, 1), |(mut acc, a, b), _| { 21 + acc.push(b); 22 + (acc, b, a + b) 23 + }) 24 + .0 25 + }
+26
rust/short-fibonacci/tests/short-fibonacci.rs
··· 1 + use short_fibonacci::*; 2 + 3 + #[test] 4 + fn test_empty() { 5 + assert_eq!(create_empty(), Vec::new()); 6 + } 7 + #[test] 8 + #[ignore] 9 + fn test_buffer() { 10 + for n in 0..10 { 11 + let zeroized = create_buffer(n); 12 + assert_eq!(zeroized.len(), n); 13 + assert!(zeroized.iter().all(|&v| v == 0)); 14 + } 15 + } 16 + #[test] 17 + #[ignore] 18 + fn test_fibonacci() { 19 + let fibb = fibonacci(); 20 + assert_eq!(fibb.len(), 5); 21 + assert_eq!(fibb[0], 1); 22 + assert_eq!(fibb[1], 1); 23 + for window in fibb.windows(3) { 24 + assert_eq!(window[0] + window[1], window[2]); 25 + } 26 + }