summaryrefslogtreecommitdiff
path: root/exercises
diff options
context:
space:
mode:
authorolivia <olivia@fastmail.com>2018-11-09 20:31:14 +0100
committerolivia <olivia@fastmail.com>2018-11-09 20:31:14 +0100
commitf7846af7ac388652a6f80a2bbce926ba8f053062 (patch)
tree954ee36257047ac612654c5f35e18ed27deda97f /exercises
parent850a13e9133fedb2fce27884902e0aab94da9692 (diff)
right let's try this one again
Diffstat (limited to 'exercises')
-rwxr-xr-xexercises/error_handling/errors1.rs73
-rwxr-xr-xexercises/error_handling/errors2.rs72
-rwxr-xr-xexercises/error_handling/errors3.rs62
-rwxr-xr-xexercises/error_handling/errorsn.rs138
-rwxr-xr-xexercises/error_handling/option1.rs45
-rwxr-xr-xexercises/error_handling/result1.rs43
-rwxr-xr-xexercises/ex1.rs6
-rwxr-xr-xexercises/ex2.rs10
-rwxr-xr-xexercises/ex3.rs10
-rwxr-xr-xexercises/ex4.rs14
-rwxr-xr-xexercises/ex5.rs22
-rwxr-xr-xexercises/functions/functions1.rs44
-rwxr-xr-xexercises/functions/functions2.rs42
-rwxr-xr-xexercises/functions/functions3.rs42
-rwxr-xr-xexercises/functions/functions4.rs44
-rwxr-xr-xexercises/functions/functions5.rs47
-rwxr-xr-xexercises/if/if1.rs58
-rwxr-xr-xexercises/macros/macros1.rs64
-rwxr-xr-xexercises/macros/macros2.rs73
-rwxr-xr-xexercises/macros/macros3.rs75
-rwxr-xr-xexercises/macros/macros4.rs77
-rwxr-xr-xexercises/modules/modules1.rs43
-rwxr-xr-xexercises/modules/modules2.rs45
-rwxr-xr-xexercises/move_semantics/move_semantics1.rs43
-rwxr-xr-xexercises/move_semantics/move_semantics2.rs54
-rwxr-xr-xexercises/move_semantics/move_semantics3.rs46
-rwxr-xr-xexercises/move_semantics/move_semantics4.rs48
-rwxr-xr-xexercises/primitive_types/primitive_types1.rs17
-rwxr-xr-xexercises/primitive_types/primitive_types2.rs27
-rwxr-xr-xexercises/primitive_types/primitive_types3.rs47
-rwxr-xr-xexercises/primitive_types/primitive_types4.rs49
-rwxr-xr-xexercises/primitive_types/primitive_types5.rs45
-rwxr-xr-xexercises/primitive_types/primitive_types6.rs45
-rwxr-xr-xexercises/standard_library_types/arc1.rs56
-rwxr-xr-xexercises/standard_library_types/iterator3.rs147
-rwxr-xr-xexercises/standard_library_types/iterators4.rs61
-rwxr-xr-xexercises/strings/strings1.rs46
-rwxr-xr-xexercises/strings/strings2.rs44
-rwxr-xr-xexercises/strings/strings3.rs21
-rwxr-xr-xexercises/tests/tests1.rs49
-rwxr-xr-xexercises/tests/tests2.rs44
-rwxr-xr-xexercises/tests/tests3.rs43
-rwxr-xr-xexercises/tests/tests4.rs19
-rwxr-xr-xexercises/threads/threads1.rs95
-rwxr-xr-xexercises/variables/variables1.rs42
-rwxr-xr-xexercises/variables/variables2.rs47
-rwxr-xr-xexercises/variables/variables3.rs43
-rwxr-xr-xexercises/variables/variables4.rs45
48 files changed, 2372 insertions, 0 deletions
diff --git a/exercises/error_handling/errors1.rs b/exercises/error_handling/errors1.rs
new file mode 100755
index 0000000..14ed574
--- /dev/null
+++ b/exercises/error_handling/errors1.rs
@@ -0,0 +1,73 @@
+// errors1.rs
+// This function refuses to generate text to be printed on a nametag if
+// you pass it an empty string. It'd be nicer if it explained what the problem
+// was, instead of just sometimes returning `None`. The 2nd test currently
+// does not compile or pass, but it illustrates the behavior we would like
+// this function to have.
+// Scroll down for hints!!!
+
+pub fn generate_nametag_text(name: String) -> Option<String> {
+ if name.len() > 0 {
+ Some(format!("Hi! My name is {}", name))
+ } else {
+ // Empty names aren't allowed.
+ None
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ // This test passes initially if you comment out the 2nd test.
+ // You'll need to update what this test expects when you change
+ // the function under test!
+ #[test]
+ fn generates_nametag_text_for_a_nonempty_name() {
+ assert_eq!(
+ generate_nametag_text("Beyoncé".into()),
+ Some("Hi! My name is Beyoncé".into())
+ );
+ }
+
+ #[test]
+ fn explains_why_generating_nametag_text_fails() {
+ assert_eq!(
+ generate_nametag_text("".into()),
+ Err("`name` was empty; it must be nonempty.".into())
+ );
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// `Err` is one of the variants of `Result`, so what the 2nd test is saying
+// is that `generate_nametag_text` should return a `Result` instead of an
+// `Option`.
+
+// To make this change, you'll need to:
+// - update the return type in the function signature to be a Result that
+// could be the variants `Ok(String)` and `Err(String)`
+// - change the body of the function to return `Ok(stuff)` where it currently
+// returns `Some(stuff)`
+// - change the body of the function to return `Err(error message)` where it
+// currently returns `None`
+// - change the first test to expect `Ok(stuff)` where it currently expects
+// `Some(stuff)`.
diff --git a/exercises/error_handling/errors2.rs b/exercises/error_handling/errors2.rs
new file mode 100755
index 0000000..15c21c8
--- /dev/null
+++ b/exercises/error_handling/errors2.rs
@@ -0,0 +1,72 @@
+// errors2.rs
+// Say we're writing a game where you can buy items with tokens. All items cost
+// 5 tokens, and whenever you purchase items there is a processing fee of 1
+// token. A player of the game will type in how many items they want to buy,
+// and the `total_cost` function will calculate the total number of tokens.
+// Since the player typed in the quantity, though, we get it as a string-- and
+// they might have typed anything, not just numbers!
+
+// Right now, this function isn't handling the error case at all (and isn't
+// handling the success case properly either). What we want to do is:
+// if we call the `parse` function on a string that is not a number, that
+// function will return a `ParseIntError`, and in that case, we want to
+// immediately return that error from our function and not try to multiply
+// and add.
+
+// There are at least two ways to implement this that are both correct-- but
+// one is a lot shorter! Scroll down for hints to both ways.
+
+use std::num::ParseIntError;
+
+pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
+ let processing_fee = 1;
+ let cost_per_item = 5;
+ let qty = item_quantity.parse::<i32>();
+
+ Ok(qty * cost_per_item + processing_fee)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn item_quantity_is_a_valid_number() {
+ assert_eq!(
+ total_cost("34"),
+ Ok(171)
+ );
+ }
+
+ #[test]
+ fn item_quantity_is_an_invalid_number() {
+ assert_eq!(
+ total_cost("beep boop").unwrap_err().to_string(),
+ "invalid digit found in string"
+ );
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// One way to handle this is using a `match` statement on
+// `item_quantity.parse::<i32>()` where the cases are `Ok(something)` and
+// `Err(something)`. This pattern is very common in Rust, though, so there's
+// a `?` operator that does pretty much what you would make that match statement
+// do for you! Take a look at this section of the Error Handling chapter:
+// https://doc.rust-lang.org/stable/book/second-edition/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
+// and give it a try!
diff --git a/exercises/error_handling/errors3.rs b/exercises/error_handling/errors3.rs
new file mode 100755
index 0000000..9c29af5
--- /dev/null
+++ b/exercises/error_handling/errors3.rs
@@ -0,0 +1,62 @@
+// errors3.rs
+// This is a program that is trying to use a completed version of the
+// `total_cost` function from the previous exercise. It's not working though--
+// we can't use the `?` operator in the `main()` function! Why not?
+// What should we do instead? Scroll for hints!
+
+use std::num::ParseIntError;
+
+fn main() {
+ let mut tokens = 100;
+ let pretend_user_input = "8";
+
+ let cost = total_cost(pretend_user_input)?;
+
+ if cost > tokens {
+ println!("You can't afford that many!");
+ } else {
+ tokens -= cost;
+ println!("You now have {} tokens.", tokens);
+ }
+}
+
+pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
+ let processing_fee = 1;
+ let cost_per_item = 5;
+ let qty = item_quantity.parse::<i32>()?;
+
+ Ok(qty * cost_per_item + processing_fee)
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Since the `?` operator returns an `Err` early if the thing it's trying to
+// do fails, you can only use the `?` operator in functions that have a
+// `Result` as their return type.
+
+// Hence the error that you get if you run this code is:
+
+// ```
+// error[E0277]: the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
+// ```
+
+// So we have to use another way of handling a `Result` within `main`.
+
+// Decide what we should do if `pretend_user_input` has a string value that does
+// not parse to an integer, and implement that instead of using the `?`
+// operator.
diff --git a/exercises/error_handling/errorsn.rs b/exercises/error_handling/errorsn.rs
new file mode 100755
index 0000000..15c6cd5
--- /dev/null
+++ b/exercises/error_handling/errorsn.rs
@@ -0,0 +1,138 @@
+// errorsn.rs
+// This is a bigger error exercise than the previous ones!
+// You can do it! :)
+//
+// Edit the `read_and_validate` function so that it compiles and
+// passes the tests... so many things could go wrong!
+//
+// - Reading from stdin could produce an io::Error
+// - Parsing the input could produce a num::ParseIntError
+// - Validating the input could produce a CreationError (defined below)
+//
+// How can we lump these errors into one general error? That is, what
+// type goes where the question marks are, and how do we return
+// that type from the body of read_and_validate?
+//
+// Scroll down for hints :)
+
+use std::error;
+use std::fmt;
+use std::io;
+
+// PositiveNonzeroInteger is a struct defined below the tests.
+fn read_and_validate(b: &mut io::BufRead) -> Result<PositiveNonzeroInteger, ???> {
+ let mut line = String::new();
+ b.read_line(&mut line);
+ let num: i64 = line.trim().parse();
+ let answer = PositiveNonzeroInteger::new(num);
+ answer
+}
+
+// This is a test helper function that turns a &str into a BufReader.
+fn test_with_str(s: &str) -> Result<PositiveNonzeroInteger, Box<error::Error>> {
+ let mut b = io::BufReader::new(s.as_bytes());
+ read_and_validate(&mut b)
+}
+
+#[test]
+fn test_success() {
+ let x = test_with_str("42\n");
+ assert_eq!(PositiveNonzeroInteger(42), x.unwrap());
+}
+
+#[test]
+fn test_not_num() {
+ let x = test_with_str("eleven billion\n");
+ assert!(x.is_err());
+}
+
+#[test]
+fn test_non_positive() {
+ let x = test_with_str("-40\n");
+ assert!(x.is_err());
+}
+
+#[test]
+fn test_ioerror() {
+ struct Broken;
+ impl io::Read for Broken {
+ fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
+ Err(io::Error::new(io::ErrorKind::BrokenPipe, "uh-oh!"))
+ }
+ }
+ let mut b = io::BufReader::new(Broken);
+ assert!(read_and_validate(&mut b).is_err());
+ assert_eq!("uh-oh!", read_and_validate(&mut b).unwrap_err().to_string());
+}
+
+#[derive(PartialEq,Debug)]
+struct PositiveNonzeroInteger(u64);
+
+impl PositiveNonzeroInteger {
+ fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
+ if value == 0 {
+ Err(CreationError::Zero)
+ } else if value < 0 {
+ Err(CreationError::Negative)
+ } else {
+ Ok(PositiveNonzeroInteger(value as u64))
+ }
+ }
+}
+
+#[test]
+fn test_positive_nonzero_integer_creation() {
+ assert!(PositiveNonzeroInteger::new(10).is_ok());
+ assert_eq!(Err(CreationError::Negative), PositiveNonzeroInteger::new(-10));
+ assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
+}
+
+#[derive(PartialEq,Debug)]
+enum CreationError {
+ Negative,
+ Zero,
+}
+
+impl fmt::Display for CreationError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str((self as &error::Error).description())
+ }
+}
+
+impl error::Error for CreationError {
+ fn description(&self) -> &str {
+ match *self {
+ CreationError::Negative => "Negative",
+ CreationError::Zero => "Zero",
+ }
+ }
+}
+
+// First hint: To figure out what type should go where the ??? is, take a look
+// at the test helper function `test_with_str`, since it returns whatever
+// `read_and_validate` returns and`test_with_str` has its signature fully
+// specified.
+
+// Next hint: There are three places in `read_and_validate` that we call a
+// function that returns a `Result` (that is, the functions might fail).
+// Apply the `?` operator on those calls so that we return immediately from
+// `read_and_validate` if those function calls fail.
+
+// Another hint: under the hood, the `?` operator calls `From::from`
+// on the error value to convert it to a boxed trait object, a Box<error::Error>,
+// which is polymorphic-- that means that lots of different kinds of errors
+// can be returned from the same function because all errors act the same
+// since they all implement the `error::Error` trait.
+// Check out this section of the book:
+// https://doc.rust-lang.org/stable/book/second-edition/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
+
+// Another another hint: Note that because the `?` operator returns
+// the *unwrapped* value in the `Ok` case, if we want to return a `Result` from
+// `read_and_validate` for *its* success case, we'll have to rewrap a value
+// that we got from the return value of a `?`ed call in an `Ok`-- this will
+// look like `Ok(something)`.
+
+// Another another another hint: `Result`s must be "used", that is, you'll
+// get a warning if you don't handle a `Result` that you get in your
+// function. Read more about that in the `std::result` module docs:
+// https://doc.rust-lang.org/std/result/#results-must-be-used
diff --git a/exercises/error_handling/option1.rs b/exercises/error_handling/option1.rs
new file mode 100755
index 0000000..9cf0bc9
--- /dev/null
+++ b/exercises/error_handling/option1.rs
@@ -0,0 +1,45 @@
+// option1.rs
+// This example panics because the second time it calls `pop`, the `vec`
+// is empty, so `pop` returns `None`, and `unwrap` panics if it's called
+// on `None`. Handle this in a more graceful way than calling `unwrap`!
+// Scroll down for hints :)
+
+fn main() {
+ let mut list = vec![3];
+
+ let last = list.pop().unwrap();
+ println!("The last item in the list is {:?}", last);
+
+ let second_to_last = list.pop().unwrap();
+ println!("The second-to-last item in the list is {:?}", second_to_last);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Try using a `match` statement where the arms are `Some(thing)` and `None`.
+// Or set a default value to print out if you get `None` by using the
+// function `unwrap_or`.
+// Or use an `if let` statement on the result of `pop()` to both destructure
+// a `Some` value and only print out something if we have a value!
diff --git a/exercises/error_handling/result1.rs b/exercises/error_handling/result1.rs
new file mode 100755
index 0000000..851ab45
--- /dev/null
+++ b/exercises/error_handling/result1.rs
@@ -0,0 +1,43 @@
+// result1.rs
+// Make this test pass! Scroll down for hints :)
+
+#[derive(PartialEq,Debug)]
+struct PositiveNonzeroInteger(u64);
+
+#[derive(PartialEq,Debug)]
+enum CreationError {
+ Negative,
+ Zero,
+}
+
+impl PositiveNonzeroInteger {
+ fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
+ Ok(PositiveNonzeroInteger(value as u64))
+ }
+}
+
+#[test]
+fn test_creation() {
+ assert!(PositiveNonzeroInteger::new(10).is_ok());
+ assert_eq!(Err(CreationError::Negative), PositiveNonzeroInteger::new(-10));
+ assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// `PositiveNonzeroInteger::new` is always creating a new instance and returning an `Ok` result.
+// It should be doing some checking, returning an `Err` result if those checks fail, and only
+// returning an `Ok` result if those checks determine that everything is... okay :)
diff --git a/exercises/ex1.rs b/exercises/ex1.rs
new file mode 100755
index 0000000..dc5f9ca
--- /dev/null
+++ b/exercises/ex1.rs
@@ -0,0 +1,6 @@
+// ex1.rs
+// Make me compile! :)
+
+fn main() {
+ println();
+}
diff --git a/exercises/ex2.rs b/exercises/ex2.rs
new file mode 100755
index 0000000..0fd714d
--- /dev/null
+++ b/exercises/ex2.rs
@@ -0,0 +1,10 @@
+// ex2.rs
+// Make me compile!
+
+fn something() -> String {
+ "hi!"
+}
+
+fn main() {
+ println!("{}", something());
+}
diff --git a/exercises/ex3.rs b/exercises/ex3.rs
new file mode 100755
index 0000000..db27ad2
--- /dev/null
+++ b/exercises/ex3.rs
@@ -0,0 +1,10 @@
+// ex3.rs
+// Make me compile!
+
+struct Foo {
+ capacity: i32,
+}
+
+fn main() {
+ println!("{:?}", Foo { capacity: 3 });
+}
diff --git a/exercises/ex4.rs b/exercises/ex4.rs
new file mode 100755
index 0000000..362a557
--- /dev/null
+++ b/exercises/ex4.rs
@@ -0,0 +1,14 @@
+// ex4.rs
+// Make me compile!
+
+fn something() -> Result<i32, std::num::ParseIntError> {
+ let x:i32 = "3".parse();
+ Ok(x * 4)
+}
+
+fn main() {
+ match something() {
+ Ok(..) => println!("You win!"),
+ Err(e) => println!("Oh no something went wrong: {}", e),
+ }
+}
diff --git a/exercises/ex5.rs b/exercises/ex5.rs
new file mode 100755
index 0000000..2eb8cfd
--- /dev/null
+++ b/exercises/ex5.rs
@@ -0,0 +1,22 @@
+// ex5.rs
+// Make me compile!
+
+enum Reaction<'a> {
+ Sad(&'a str),
+ Happy(&'a str),
+}
+
+fn express(sentiment: Reaction) {
+ match sentiment {
+ Reaction::Sad(s) => println!(":( {}", s),
+ Reaction::Happy(s) => println!(":) {}", s),
+ }
+}
+
+fn main () {
+ let x = Reaction::Happy("It's a great day for Rust!");
+ express(x);
+ express(x);
+ let y = Reaction::Sad("This code doesn't compile yet.");
+ express(y);
+}
diff --git a/exercises/functions/functions1.rs b/exercises/functions/functions1.rs
new file mode 100755
index 0000000..396dd56
--- /dev/null
+++ b/exercises/functions/functions1.rs
@@ -0,0 +1,44 @@
+// functions1.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ call_me();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// This main function is calling a function that it expects to exist, but the
+// function doesn't exist. It expects this function to have the name `call_me`.
+// It expects this function to not take any arguments and not return a value.
+// Sounds a lot like `main`, doesn't it?
diff --git a/exercises/functions/functions2.rs b/exercises/functions/functions2.rs
new file mode 100755
index 0000000..1cf95c3
--- /dev/null
+++ b/exercises/functions/functions2.rs
@@ -0,0 +1,42 @@
+// functions2.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ call_me(3);
+}
+
+fn call_me(num) {
+ for i in 0..num {
+ println!("Ring! Call number {}", i + 1);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Rust requires that all parts of a function's signature have type annotations,
+// but `call_me` is missing the type annotation of `num`.
diff --git a/exercises/functions/functions3.rs b/exercises/functions/functions3.rs
new file mode 100755
index 0000000..b17543b
--- /dev/null
+++ b/exercises/functions/functions3.rs
@@ -0,0 +1,42 @@
+// functions3.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ call_me();
+}
+
+fn call_me(num: i32) {
+ for i in 0..num {
+ println!("Ring! Call number {}", i + 1);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// This time, the function *declaration* is okay, but there's something wrong
+// with the place where we're calling the function.
diff --git a/exercises/functions/functions4.rs b/exercises/functions/functions4.rs
new file mode 100755
index 0000000..5baca0e
--- /dev/null
+++ b/exercises/functions/functions4.rs
@@ -0,0 +1,44 @@
+// functions4.rs
+// Make me compile! Scroll down for hints :)
+
+// This store is having a sale where if the price is an even number, you get
+// 10 (money unit) off, but if it's an odd number, it's 3 (money unit) less.
+
+fn main() {
+ let original_price = 51;
+ println!("Your sale price is {}", sale_price(original_price));
+}
+
+fn sale_price(price: i32) -> {
+ if is_even(price) {
+ price - 10
+ } else {
+ price - 3
+ }
+}
+
+fn is_even(num: i32) -> bool {
+ num % 2 == 0
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// The error message points to line 12 and says it expects a type after the
+// `->`. This is where the function's return type should be-- take a look at
+// the `is_even` function for an example!
diff --git a/exercises/functions/functions5.rs b/exercises/functions/functions5.rs
new file mode 100755
index 0000000..d3ff002
--- /dev/null
+++ b/exercises/functions/functions5.rs
@@ -0,0 +1,47 @@
+// functions5.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ let answer = square(3);
+ println!("The answer is {}", answer);
+}
+
+fn square(num: i32) -> i32 {
+ num * num;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// This is a really common error that can be fixed by removing one character.
+// It happens because Rust distinguishes between expressions and statements: expressions return
+// a value based on its operand, and statements simply return a () type which behaves just like `void` in C/C++ language.
+// We want to return a value of `i32` type from the `square` function, but it is returning a `()` type...
+// They are not the same. There are two solutions:
+// 1. Add a `return` ahead of `num * num;`
+// 2. remove `;`, make it to be `num * num`
diff --git a/exercises/if/if1.rs b/exercises/if/if1.rs
new file mode 100755
index 0000000..5118657
--- /dev/null
+++ b/exercises/if/if1.rs
@@ -0,0 +1,58 @@
+// if1.rs
+
+pub fn bigger(a: i32, b:i32) -> i32 {
+ // Complete this function to return the bigger number!
+ // Do not use:
+ // - return
+ // - another function call
+ // - additional variables
+ // Scroll down for hints.
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn ten_is_bigger_than_eight() {
+ assert_eq!(10, bigger(10, 8));
+ }
+
+ #[test]
+ fn fortytwo_is_bigger_than_thirtytwo() {
+ assert_eq!(42, bigger(32, 42));
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// It's possible to do this in one line if you would like!
+// Some similar examples from other languages:
+// - In C(++) this would be: `a > b ? a : b`
+// - In Python this would be: `a if a > b else b`
+// Remember in Rust that:
+// - the `if` condition does not need to be surrounded by parentheses
+// - `if`/`else` conditionals are expressions
+// - Each condition is followed by a `{}` block.
diff --git a/exercises/macros/macros1.rs b/exercises/macros/macros1.rs
new file mode 100755
index 0000000..a7c78a5
--- /dev/null
+++ b/exercises/macros/macros1.rs
@@ -0,0 +1,64 @@
+// macros1.rs
+// Make me compile! Scroll down for hints :)
+
+macro_rules! my_macro {
+ () => {
+ println!("Check out my macro!");
+ };
+}
+
+fn main() {
+ my_macro();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// When you call a macro, you need to add something special compared to a
+// regular function call. If you're stuck, take a look at what's inside
+// `my_macro`.
diff --git a/exercises/macros/macros2.rs b/exercises/macros/macros2.rs
new file mode 100755
index 0000000..bc2e56b
--- /dev/null
+++ b/exercises/macros/macros2.rs
@@ -0,0 +1,73 @@
+// macros2.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ my_macro!();
+}
+
+macro_rules! my_macro {
+ () => {
+ println!("Check out my macro!");
+ };
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Macros don't quite play by the same rules as the rest of Rust, in terms of
+// what's available where.
+
+
+
+
+
+
+
+
+// Unlike other things in Rust, the order of "where you define a macro" versus
+// "where you use it" actually matters.
diff --git a/exercises/macros/macros3.rs b/exercises/macros/macros3.rs
new file mode 100755
index 0000000..84c4308
--- /dev/null
+++ b/exercises/macros/macros3.rs
@@ -0,0 +1,75 @@
+// macros3.rs
+// Make me compile, without taking the macro out of the module! Scroll down for hints :)
+
+mod macros {
+ macro_rules! my_macro {
+ () => {
+ println!("Check out my macro!");
+ };
+ }
+}
+
+fn main() {
+ my_macro!();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// In order to use a macro outside of its module, you need to do something
+// special to the module to lift the macro out into its parent.
+
+
+
+
+
+
+
+
+// The same trick also works on "extern crate" statements for crates that have
+// exported macros, if you've seen any of those around.
diff --git a/exercises/macros/macros4.rs b/exercises/macros/macros4.rs
new file mode 100755
index 0000000..d844bb0
--- /dev/null
+++ b/exercises/macros/macros4.rs
@@ -0,0 +1,77 @@
+// macros4.rs
+// Make me compile! Scroll down for hints :)
+
+macro_rules! my_macro {
+ () => {
+ println!("Check out my macro!");
+ }
+ ($val:expr) => {
+ println!("Look at this other macro: {}", $val);
+ }
+}
+
+fn main() {
+ my_macro!();
+ my_macro!(7777);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// You only need to add a single character to make this compile.
+
+
+
+
+
+
+
+
+
+// The way macros are written, it wants to see something between each
+// "macro arm", so it can separate them.
diff --git a/exercises/modules/modules1.rs b/exercises/modules/modules1.rs
new file mode 100755
index 0000000..0e092c5
--- /dev/null
+++ b/exercises/modules/modules1.rs
@@ -0,0 +1,43 @@
+// modules1.rs
+// Make me compile! Scroll down for hints :)
+
+mod sausage_factory {
+ fn make_sausage() {
+ println!("sausage!");
+ }
+}
+
+fn main() {
+ sausage_factory::make_sausage();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Everything is private in Rust by default-- but there's a keyword we can use
+// to make something public! The compiler error should point to the thing that
+// needs to be public.
diff --git a/exercises/modules/modules2.rs b/exercises/modules/modules2.rs
new file mode 100755
index 0000000..164dfb0
--- /dev/null
+++ b/exercises/modules/modules2.rs
@@ -0,0 +1,45 @@
+// modules2.rs
+// Make me compile! Scroll down for hints :)
+
+mod us_presidential_frontrunners {
+ use self::democrats::HILLARY_CLINTON as democrat;
+ use self::republicans::DONALD_TRUMP as republican;
+
+ mod democrats {
+ pub const HILLARY_CLINTON: &'static str = "Hillary Clinton";
+ pub const BERNIE_SANDERS: &'static str = "Bernie Sanders";
+ }
+
+ mod republicans {
+ pub const DONALD_TRUMP: &'static str = "Donald Trump";
+ pub const JEB_BUSH: &'static str = "Jeb Bush";
+ }
+}
+
+fn main() {
+ println!("candidates: {} and {}",
+ us_presidential_frontrunners::democrat,
+ us_presidential_frontrunners::republican);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// The us_presidential_frontrunners module is trying to present an external
+// interface (the `democrat` and `republican` constants) that is different than
+// its internal structure (the `democrats` and `republicans` modules and
+// associated constants). It's almost there except for one keyword missing for
+// each constant.
diff --git a/exercises/move_semantics/move_semantics1.rs b/exercises/move_semantics/move_semantics1.rs
new file mode 100755
index 0000000..37038ec
--- /dev/null
+++ b/exercises/move_semantics/move_semantics1.rs
@@ -0,0 +1,43 @@
+// move_semantics1.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ let vec0 = Vec::new();
+
+ let vec1 = fill_vec(vec0);
+
+ println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
+
+ vec1.push(88);
+
+ println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
+
+}
+
+fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
+ let mut vec = vec;
+
+ vec.push(22);
+ vec.push(44);
+ vec.push(66);
+
+ vec
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// So you've got the "cannot borrow immutable local variable `vec1` as mutable" error on line 11,
+// right? The fix for this is going to be adding one keyword, and the addition is NOT on line 11
+// where the error is.
diff --git a/exercises/move_semantics/move_semantics2.rs b/exercises/move_semantics/move_semantics2.rs
new file mode 100755
index 0000000..b50e349
--- /dev/null
+++ b/exercises/move_semantics/move_semantics2.rs
@@ -0,0 +1,54 @@
+// move_semantics2.rs
+// Make me compile without changing line 10! Scroll down for hints :)
+
+fn main() {
+ let vec0 = Vec::new();
+
+ let mut vec1 = fill_vec(vec0);
+
+ // Do not change the following line!
+ println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);
+
+ vec1.push(88);
+
+ println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
+
+}
+
+fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
+ let mut vec = vec;
+
+ vec.push(22);
+ vec.push(44);
+ vec.push(66);
+
+ vec
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// So `vec0` is being *moved* into the function `fill_vec` when we call it on
+// line 7, which means it gets dropped at the end of `fill_vec`, which means we
+// can't use `vec0` again on line 10 (or anywhere else in `main` after the
+// `fill_vec` call for that matter). We could fix this in a few ways, try them
+// all!
+// 1. Make another, separate version of the data that's in `vec0` and pass that
+// to `fill_vec` instead.
+// 2. Make `fill_vec` borrow its argument instead of taking ownership of it,
+// and then copy the data within the function in order to return an owned
+// `Vec<i32>`
+// 3. Make `fill_vec` *mutably* borrow its argument (which will need to be
+// mutable), modify it directly, then not return anything. Then you can get rid
+// of `vec1` entirely -- note that this will change what gets printed by the
+// first `println!`
diff --git a/exercises/move_semantics/move_semantics3.rs b/exercises/move_semantics/move_semantics3.rs
new file mode 100755
index 0000000..8e7b0ad
--- /dev/null
+++ b/exercises/move_semantics/move_semantics3.rs
@@ -0,0 +1,46 @@
+// move_semantics3.rs
+// Make me compile without adding new lines-- just changing existing lines!
+// (no lines with multiple semicolons necessary!)
+// Scroll down for hints :)
+
+fn main() {
+ let vec0 = Vec::new();
+
+ let mut vec1 = fill_vec(vec0);
+
+ println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
+
+ vec1.push(88);
+
+ println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
+
+}
+
+fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
+ vec.push(22);
+ vec.push(44);
+ vec.push(66);
+
+ vec
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// The difference between this one and the previous ones is that the first line
+// of `fn fill_vec` that had `let mut vec = vec;` is no longer there. You can,
+// instead of adding that line back, add `mut` in one place that will change
+// an existing binding to be a mutable binding instead of an immutable one :)
diff --git a/exercises/move_semantics/move_semantics4.rs b/exercises/move_semantics/move_semantics4.rs
new file mode 100755
index 0000000..903a330
--- /dev/null
+++ b/exercises/move_semantics/move_semantics4.rs
@@ -0,0 +1,48 @@
+// move_semantics4.rs
+// Refactor this code so that instead of having `vec0` and creating the vector
+// in `fn main`, we instead create it within `fn fill_vec` and transfer the
+// freshly created vector from fill_vec to its caller. Scroll for hints!
+
+fn main() {
+ let vec0 = Vec::new();
+
+ let mut vec1 = fill_vec(vec0);
+
+ println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
+
+ vec1.push(88);
+
+ println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
+
+}
+
+fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
+ let mut vec = vec;
+
+ vec.push(22);
+ vec.push(44);
+ vec.push(66);
+
+ vec
+}
+
+
+
+
+
+
+
+
+
+
+
+
+// Stop reading whenever you feel like you have enough direction :) Or try
+// doing one step and then fixing the compiler errors that result!
+// So the end goal is to:
+// - get rid of the first line in main that creates the new vector
+// - so then `vec0` doesn't exist, so we can't pass it to `fill_vec`
+// - we don't want to pass anything to `fill_vec`, so its signature should
+// reflect that it does not take any arguments
+// - since we're not creating a new vec in `main` anymore, we need to create
+// a new vec in `fill_vec`, similarly to the way we did in `main`
diff --git a/exercises/primitive_types/primitive_types1.rs b/exercises/primitive_types/primitive_types1.rs
new file mode 100755
index 0000000..c3d11fe
--- /dev/null
+++ b/exercises/primitive_types/primitive_types1.rs
@@ -0,0 +1,17 @@
+// primitive_types1.rs
+// Fill in the rest of the line that has code missing!
+// No hints, there's no tricks, just get used to typing these :)
+
+fn main() {
+ // Booleans (`bool`)
+
+ let is_morning = true;
+ if is_morning {
+ println!("Good morning!");
+ }
+
+ let // Finish the rest of this line like the example! Or make it be false!
+ if is_evening {
+ println!("Good evening!");
+ }
+}
diff --git a/exercises/primitive_types/primitive_types2.rs b/exercises/primitive_types/primitive_types2.rs
new file mode 100755
index 0000000..f5c8f87
--- /dev/null
+++ b/exercises/primitive_types/primitive_types2.rs
@@ -0,0 +1,27 @@
+// primitive_types2.rs
+// Fill in the rest of the line that has code missing!
+// No hints, there's no tricks, just get used to typing these :)
+
+fn main() {
+ // Characters (`char`)
+
+ let my_first_initial = 'C';
+ if my_first_initial.is_alphabetic() {
+ println!("Alphabetical!");
+ } else if my_first_initial.is_numeric() {
+ println!("Numerical!");
+ } else {
+ println!("Neither alphabetic nor numeric!");
+ }
+
+ let // Finish this line like the example! What's your favorite character?
+ // Try a letter, try a number, try a special character, try a character
+ // from a different language than your own, try an emoji!
+ if your_character.is_alphabetic() {
+ println!("Alphabetical!");
+ } else if your_character.is_numeric() {
+ println!("Numerical!");
+ } else {
+ println!("Neither alphabetic nor numeric!");
+ }
+}
diff --git a/exercises/primitive_types/primitive_types3.rs b/exercises/primitive_types/primitive_types3.rs
new file mode 100755
index 0000000..7ce2226
--- /dev/null
+++ b/exercises/primitive_types/primitive_types3.rs
@@ -0,0 +1,47 @@
+// primitive_types3.rs
+// Create an array with at least 100 elements in it where the ??? is.
+// Scroll down for hints!
+
+fn main() {
+ let a = ???
+
+ if a.len() >= 100 {
+ println!("Wow, that's a big array!");
+ } else {
+ println!("Meh, I eat arrays like that for breakfast.");
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// There's a shorthand to initialize Arrays with a certain size that does not
+// require you to type in 100 items (but you certainly can if you want!).
+// For example, you can do:
+// let array = ["Are we there yet?"; 10];
+
+// Bonus: what are some other things you could have that would return true
+// for `a.len() >= 100`?
diff --git a/exercises/primitive_types/primitive_types4.rs b/exercises/primitive_types/primitive_types4.rs
new file mode 100755
index 0000000..7dc9e47
--- /dev/null
+++ b/exercises/primitive_types/primitive_types4.rs
@@ -0,0 +1,49 @@
+// primitive_types4.rs
+// Get a slice out of Array a where the ??? is so that the `if` statement
+// returns true. Scroll down for hints!!
+
+fn main() {
+ let a = [1, 2, 3, 4, 5];
+
+ let nice_slice = ???
+
+ if nice_slice == [2, 3, 4] {
+ println!("Nice slice!");
+ } else {
+ println!("Not quite what I was expecting... I see: {:?}", nice_slice);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Take a look at the Understanding Ownership -> Slices -> Other Slices section of the book:
+// https://doc.rust-lang.org/stable/book/second-edition/ch04-03-slices.html#other-slices
+// and use the starting and ending indices of the items in the Array
+// that you want to end up in the slice.
+
+// If you're curious why the right hand of the `==` comparison does not
+// have an ampersand for a reference since the left hand side is a
+// reference, take a look at the Deref coercions section of the book:
+// https://doc.rust-lang.org/stable/book/second-edition/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods
diff --git a/exercises/primitive_types/primitive_types5.rs b/exercises/primitive_types/primitive_types5.rs
new file mode 100755
index 0000000..4045e78
--- /dev/null
+++ b/exercises/primitive_types/primitive_types5.rs
@@ -0,0 +1,45 @@
+// primitive_types5.rs
+// Destructure the `cat` tuple so that the println will work.
+// Scroll down for hints!
+
+fn main() {
+ let cat = ("Furry McFurson", 3.5);
+ let /* your pattern here */ = cat;
+
+ println!("{} is {} years old.", name, age);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Take a look at the Data Types -> The Tuple Type section of the book:
+// https://doc.rust-lang.org/stable/book/second-edition/ch03-02-data-types.html#the-tuple-type
+// Particularly the part about destructuring (second to last example in the section).
+// You'll need to make a pattern to bind `name` and `age` to the appropriate parts
+// of the tuple. You can do it!!
diff --git a/exercises/primitive_types/primitive_types6.rs b/exercises/primitive_types/primitive_types6.rs
new file mode 100755
index 0000000..439a56b
--- /dev/null
+++ b/exercises/primitive_types/primitive_types6.rs
@@ -0,0 +1,45 @@
+// primitive_types6.rs
+// Use a tuple index to access the second element of `numbers`.
+// You can put this right into the `println!` where the ??? is.
+// Scroll down for hints!
+
+fn main() {
+ let numbers = (1, 2, 3);
+ println!("The second number is {}", ???);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// While you could use a destructuring `let` for the tuple here, try
+// indexing into it instead, as explained in the last example of the
+// Data Types -> The Tuple Type section of the book:
+// https://doc.rust-lang.org/stable/book/second-edition/ch03-02-data-types.html#the-tuple-type
+// Now you have another tool in your toolbox!
diff --git a/exercises/standard_library_types/arc1.rs b/exercises/standard_library_types/arc1.rs
new file mode 100755
index 0000000..c744a10
--- /dev/null
+++ b/exercises/standard_library_types/arc1.rs
@@ -0,0 +1,56 @@
+// arc1.rs
+// Make this code compile by filling in a value for `shared_numbers` where the
+// TODO comment is and creating an initial binding for `child_numbers`
+// somewhere. Try not to create any copies of the `numbers` Vec!
+// Scroll down for hints :)
+
+use std::sync::Arc;
+use std::thread;
+
+fn main() {
+ let numbers: Vec<_> = (0..100u32).collect();
+ let shared_numbers = // TODO
+ let mut joinhandles = Vec::new();
+
+ for offset in 0..8 {
+ joinhandles.push(
+ thread::spawn(move || {
+ let mut i = offset;
+ let mut sum = 0;
+ while i < child_numbers.len() {
+ sum += child_numbers[i];
+ i += 5;
+ }
+ println!("Sum of offset {} is {}", offset, sum);
+ }));
+ }
+ for handle in joinhandles.into_iter() {
+ handle.join().unwrap();
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Make `shared_numbers` be an `Arc` from the numbers vector. Then, in order
+// to avoid creating a copy of `numbers`, you'll need to create `child_numbers`
+// inside the loop but still in the main thread.
+
+// `child_numbers` should be a clone of the Arc of the numbers instead of a
+// thread-local copy of the numbers.
diff --git a/exercises/standard_library_types/iterator3.rs b/exercises/standard_library_types/iterator3.rs
new file mode 100755
index 0000000..1d2e135
--- /dev/null
+++ b/exercises/standard_library_types/iterator3.rs
@@ -0,0 +1,147 @@
+// iterator3.rs
+// This is a bigger exercise than most of the others! You can do it!
+// Here is your mission, should you choose to accept it:
+// 1. Complete the divide function to get the first four tests to pass
+// 2. Uncomment the last two tests and get them to pass by filling in
+// values for `x` using `division_results`.
+// Scroll down for a minor hint for part 2, and scroll down further for
+// a major hint.
+// Have fun :-)
+
+#[derive(Debug, PartialEq, Eq)]
+pub enum DivisionError {
+ NotDivisible(NotDivisibleError),
+ DivideByZero,
+}
+
+#[derive(Debug, PartialEq, Eq)]
+pub struct NotDivisibleError {
+ dividend: i32,
+ divisor: i32,
+}
+
+// This function should calculate `a` divided by `b` if `a` is
+// evenly divisible by b.
+// Otherwise, it should return a suitable error.
+pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ // Tests that verify your `divide` function implementation
+ #[test]
+ fn test_success() {
+ assert_eq!(divide(81, 9), Ok(9));
+ }
+
+ #[test]
+ fn test_not_divisible() {
+ assert_eq!(
+ divide(81, 6),
+ Err(DivisionError::NotDivisible(NotDivisibleError{
+ dividend: 81,
+ divisor: 6
+ }))
+ );
+ }
+
+ #[test]
+ fn test_divide_by_0() {
+ assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero));
+ }
+
+ #[test]
+ fn test_divide_0_by_something() {
+ assert_eq!(divide(0, 81), Ok(0));
+ }
+
+ // Iterator exercises using your `divide` function
+ /*
+ #[test]
+ fn result_with_list() {
+ let numbers = vec![27, 297, 38502, 81];
+ let division_results = numbers.into_iter().map(|n| divide(n, 27));
+ let x //... Fill in here!
+ assert_eq!(format!("{:?}", x), "Ok([1, 11, 1426, 3])");
+ }
+
+ #[test]
+ fn list_of_results() {
+ let numbers = vec![27, 297, 38502, 81];
+ let division_results = numbers.into_iter().map(|n| divide(n, 27));
+ let x //... Fill in here!
+ assert_eq!(format!("{:?}", x), "[Ok(1), Ok(11), Ok(1426), Ok(3)]");
+ }
+ */
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Minor hint: In each of the two cases in the match in main, you can create x with either
+// a 'turbofish' or by hinting the type of x to the compiler. You may try both.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Major hint: Have a look at the Iter trait and at the explanation of its collect function.
+// Especially the part about Result is interesting.
diff --git a/exercises/standard_library_types/iterators4.rs b/exercises/standard_library_types/iterators4.rs
new file mode 100755
index 0000000..13613a6
--- /dev/null
+++ b/exercises/standard_library_types/iterators4.rs
@@ -0,0 +1,61 @@
+// iterators4.rs
+
+pub fn factorial(num: u64) -> u64 {
+ // Complete this function to return factorial of num
+ // Do not use:
+ // - return
+ // For extra fun don't use:
+ // - imperative style loops (for, while)
+ // - additional variables
+ // For the most fun don't use:
+ // - recursion
+ // Scroll down for hints.
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn factorial_of_1() {
+ assert_eq!(1, factorial(1));
+ }
+ #[test]
+ fn factorial_of_2() {
+ assert_eq!(2, factorial(2));
+ }
+
+ #[test]
+ fn factorial_of_4() {
+ assert_eq!(24, factorial(4));
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// In an imperative language you might write a for loop to iterate through
+// multiply the values into a mutable variable. Or you might write code more
+// functionally with recursion and a match clause. But you can also use ranges
+// and iterators to solve this in rust.
diff --git a/exercises/strings/strings1.rs b/exercises/strings/strings1.rs
new file mode 100755
index 0000000..2e5088f
--- /dev/null
+++ b/exercises/strings/strings1.rs
@@ -0,0 +1,46 @@
+// strings1.rs
+// Make me compile without changing the function signature! Scroll down for hints :)
+
+fn main() {
+ let answer = current_favorite_color();
+ println!("My current favorite color is {}", answer);
+}
+
+fn current_favorite_color() -> String {
+ "blue"
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// The `current_favorite_color` function is currently returning a string slice with the `'static`
+// lifetime. We know this because the data of the string lives in our code itself -- it doesn't
+// come from a file or user input or another program -- so it will live as long as our program
+// lives. But it is still a string slice. There's one way to create a `String` by converting a
+// string slice covered in the Strings chapter of the book, and another way that uses the `From`
+// trait.
diff --git a/exercises/strings/strings2.rs b/exercises/strings/strings2.rs
new file mode 100755
index 0000000..c77e16f
--- /dev/null
+++ b/exercises/strings/strings2.rs
@@ -0,0 +1,44 @@
+// strings2.rs
+// Make me compile without changing the function signature! Scroll down for hints :)
+
+fn main() {
+ let word = String::from("green"); // Try not changing this line :)
+ if is_a_color_word(word) {
+ println!("That is a color word I know!");
+ } else {
+ println!("That is not a color word I know.");
+ }
+}
+
+fn is_a_color_word(attempt: &str) -> bool {
+ attempt == "green" || attempt == "blue" || attempt == "red"
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Yes, it would be really easy to fix this by just changing the value bound to `word` to be a
+// string slice instead of a `String`, wouldn't it?? There is a way to add one character to line
+// 6, though, that will coerce the `String` into a string slice.
diff --git a/exercises/strings/strings3.rs b/exercises/strings/strings3.rs
new file mode 100755
index 0000000..b6f6a1e
--- /dev/null
+++ b/exercises/strings/strings3.rs
@@ -0,0 +1,21 @@
+// strings3.rs
+// Ok, here are a bunch of values-- some are `Strings`, some are `&strs`. Your
+// task is to call one of these two functions on each value depending on what
+// you think each value is. That is, add either `string_slice` or `string`
+// before the parentheses on each line. If you're right, it will compile!
+
+fn string_slice(arg: &str) { println!("{}", arg); }
+fn string(arg: String) { println!("{}", arg); }
+
+fn main() {
+ ("blue");
+ ("red".to_string());
+ (String::from("hi"));
+ ("rust is fun!".to_owned());
+ ("nice weather".into());
+ (format!("Interpolation {}", "Station"));
+ (&String::from("abc")[0..1]);
+ (" hello there ".trim());
+ ("Happy Monday!".to_string().replace("Mon", "Tues"));
+ ("mY sHiFt KeY iS sTiCkY".to_lowercase());
+}
diff --git a/exercises/tests/tests1.rs b/exercises/tests/tests1.rs
new file mode 100755
index 0000000..959ed85
--- /dev/null
+++ b/exercises/tests/tests1.rs
@@ -0,0 +1,49 @@
+// tests1.rs
+// Tests are important to ensure that your code does what you think it should do.
+// Tests can be run on this file with the following command:
+// rustc --test tests1.rs
+
+// This test has a problem with it -- make the test compile! Make the test
+// pass! Make the test fail! Scroll down for hints :)
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn you_can_assert() {
+ assert!();
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// You don't even need to write any code to test -- you can just test values and run that, even
+// though you wouldn't do that in real life :) `assert!` is a macro that needs an argument.
+// Depending on the value of the argument, `assert!` will do nothing (in which case the test will
+// pass) or `assert!` will panic (in which case the test will fail). So try giving different values
+// to `assert!` and see which ones compile, which ones pass, and which ones fail :)
diff --git a/exercises/tests/tests2.rs b/exercises/tests/tests2.rs
new file mode 100755
index 0000000..6775d61
--- /dev/null
+++ b/exercises/tests/tests2.rs
@@ -0,0 +1,44 @@
+// tests2.rs
+// This test has a problem with it -- make the test compile! Make the test
+// pass! Make the test fail! Scroll down for hints :)
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn you_can_assert_eq() {
+ assert_eq!();
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Like the previous exercise, you don't need to write any code to get this test to compile and
+// run. `assert_eq!` is a macro that takes two arguments and compares them. Try giving it two
+// values that are equal! Try giving it two arguments that are different! Try giving it two values
+// that are of different types! Try switching which argument comes first and which comes second!
diff --git a/exercises/tests/tests3.rs b/exercises/tests/tests3.rs
new file mode 100755
index 0000000..e041f38
--- /dev/null
+++ b/exercises/tests/tests3.rs
@@ -0,0 +1,43 @@
+// tests3.rs
+// This test isn't testing our function -- make it do that in such a way that
+// the test passes. Then write a second test that tests that we get the result
+// we expect to get when we call `is_even(5)`. Scroll down for hints!
+
+pub fn is_even(num: i32) -> bool {
+ num % 2 == 0
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn is_true_when_even() {
+ assert!(false);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// You can call a function right where you're passing arguments to `assert!` -- so you could do
+// something like `assert!(having_fun())`. If you want to check that you indeed get false, you
+// can negate the result of what you're doing using `!`, like `assert!(!having_fun())`.
diff --git a/exercises/tests/tests4.rs b/exercises/tests/tests4.rs
new file mode 100755
index 0000000..23d444a
--- /dev/null
+++ b/exercises/tests/tests4.rs
@@ -0,0 +1,19 @@
+// tests4.rs
+// This test isn't testing our function -- make it do that in such a way that
+// the test passes. Then write a second test that tests that we get the result
+// we expect to get when we call `times_two` with a negative number.
+// No hints, you can do this :)
+
+pub fn times_two(num: i32) -> i32 {
+ num * 2
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn returns_twice_of_positive_numbers() {
+ assert_eq!(4, 4);
+ }
+}
diff --git a/exercises/threads/threads1.rs b/exercises/threads/threads1.rs
new file mode 100755
index 0000000..4f9aa89
--- /dev/null
+++ b/exercises/threads/threads1.rs
@@ -0,0 +1,95 @@
+// threads1.rs
+// Make this compile! Scroll down for hints :) The idea is the thread
+// spawned on line 19 is completing jobs while the main thread is
+// monitoring progress until 10 jobs are completed. If you see 6 lines
+// of "waiting..." and the program ends without timing out the playground,
+// you've got it :)
+
+use std::sync::Arc;
+use std::thread;
+use std::time::Duration;
+
+struct JobStatus {
+ jobs_completed: u32,
+}
+
+fn main() {
+ let status = Arc::new(JobStatus { jobs_completed: 0 });
+ let status_shared = status.clone();
+ thread::spawn(move || {
+ for _ in 0..10 {
+ thread::sleep(Duration::from_millis(250));
+ status_shared.jobs_completed += 1;
+ }
+ });
+ while status.jobs_completed < 10 {
+ println!("waiting... ");
+ thread::sleep(Duration::from_millis(500));
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// `Arc` is an Atomic Reference Counted pointer that allows safe, shared access
+// to **immutable** data. But we want to *change* the number of `jobs_completed`
+// so we'll need to also use another type that will only allow one thread to
+// mutate the data at a time. Take a look at this section of the book:
+// https://doc.rust-lang.org/stable/book/second-edition/ch16-03-shared-state.html#atomic-reference-counting-with-arct
+// and keep scrolling if you'd like more hints :)
+
+
+
+
+
+
+
+
+
+
+// Do you now have an `Arc` `Mutex` `JobStatus` at the beginning of main? Like:
+// `let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));`
+// Similar to the code in the example in the book that happens after the text
+// that says "We can use Arc<T> to fix this.". If not, give that a try! If you
+// do and would like more hints, keep scrolling!!
+
+
+
+
+
+
+
+
+
+
+
+
+// Make sure neither of your threads are holding onto the lock of the mutex
+// while they are sleeping, since this will prevent the other thread from
+// being allowed to get the lock. Locks are automatically released when
+// they go out of scope.
+
+// Ok, so, real talk, this was actually tricky for *me* to do too. And
+// I could see a lot of different problems you might run into, so at this
+// point I'm not sure which one you've hit :) Please see a few possible
+// answers on https://github.com/carols10cents/rustlings/issues/3 --
+// mine is a little more complicated because I decided I wanted to see
+// the number of jobs currently done when I was checking the status.
+
+// Please open an issue if you're still running into a problem that
+// these hints are not helping you with, or if you've looked at the sample
+// answers and don't understand why they work and yours doesn't.
+
+// If you've learned from the sample solutions, I encourage you to come
+// back to this exercise and try it again in a few days to reinforce
+// what you've learned :)
diff --git a/exercises/variables/variables1.rs b/exercises/variables/variables1.rs
new file mode 100755
index 0000000..1cdd270
--- /dev/null
+++ b/exercises/variables/variables1.rs
@@ -0,0 +1,42 @@
+// variables1.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ x = 5;
+ println!("x has the value {}", x);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Hint: The declaration on line 5 is missing a keyword that is needed in Rust
+// to create a new variable binding.
diff --git a/exercises/variables/variables2.rs b/exercises/variables/variables2.rs
new file mode 100755
index 0000000..a0b4a37
--- /dev/null
+++ b/exercises/variables/variables2.rs
@@ -0,0 +1,47 @@
+// variables2.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ let x;
+ if x == 10 {
+ println!("Ten!");
+ } else {
+ println!("Not ten!");
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// The compiler message is saying that Rust cannot infer the type that the
+// variable binding `x` has with what is given here.
+// What happens if you annotate line 5 with a type annotation?
+// What if you give x a value?
+// What if you do both?
+// What type should x be, anyway?
+// What if x is the same type as 10? What if it's a different type?
diff --git a/exercises/variables/variables3.rs b/exercises/variables/variables3.rs
new file mode 100755
index 0000000..165a277
--- /dev/null
+++ b/exercises/variables/variables3.rs
@@ -0,0 +1,43 @@
+// variables3.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ let x = 3;
+ println!("Number {}", x);
+ x = 5;
+ println!("Number {}", x);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// In Rust, variable bindings are immutable by default. But here we're trying
+// to reassign a different value to x! There's a keyword we can use to make
+// a variable binding mutable instead.
diff --git a/exercises/variables/variables4.rs b/exercises/variables/variables4.rs
new file mode 100755
index 0000000..71ebf0f
--- /dev/null
+++ b/exercises/variables/variables4.rs
@@ -0,0 +1,45 @@
+// variables4.rs
+// Make me compile! Scroll down for hints :)
+
+fn main() {
+ let x: i32;
+ println!("Number {}", x);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Oops! In this exercise, we have a variable binding that we've created on
+// line 5, and we're trying to use it on line 6, but we haven't given it a
+// value. We can't print out something that isn't there; try giving x a value!
+// This is an error that can cause bugs that's very easy to make in any
+// programming language -- thankfully the Rust compiler has caught this for us!