mirror of
https://github.com/rust-lang/rustlings.git
synced 2026-01-07 03:09:19 +00:00
Finish exercises
This commit is contained in:
parent
58fc67525b
commit
9d46b94f9f
@ -2,16 +2,15 @@
|
|||||||
// Read more about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html
|
// Read more about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html
|
||||||
// and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.
|
// and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
// Obtain the number of bytes (not characters) in the given argument
|
// Obtain the number of bytes (not characters) in the given argument
|
||||||
// Add the AsRef trait appropriately as a trait bound
|
// Add the AsRef trait appropriately as a trait bound
|
||||||
fn byte_counter<T>(arg: T) -> usize {
|
fn byte_counter<T: AsRef<str>>(arg: T) -> usize {
|
||||||
arg.as_ref().as_bytes().len()
|
arg.as_ref().as_bytes().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the number of characters (not bytes) in the given argument
|
// Obtain the number of characters (not bytes) in the given argument
|
||||||
// Add the AsRef trait appropriately as a trait bound
|
// Add the AsRef trait appropriately as a trait bound
|
||||||
fn char_counter<T>(arg: T) -> usize {
|
fn char_counter<T: AsRef<str> >(arg: T) -> usize {
|
||||||
arg.as_ref().chars().count()
|
arg.as_ref().chars().count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,6 @@ impl Default for Person {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
// Your task is to complete this implementation
|
// Your task is to complete this implementation
|
||||||
// in order for the line `let p = Person::from("Mark,20")` to compile
|
// in order for the line `let p = Person::from("Mark,20")` to compile
|
||||||
// Please note that you'll need to parse the age component into a `usize`
|
// Please note that you'll need to parse the age component into a `usize`
|
||||||
@ -34,6 +33,18 @@ impl Default for Person {
|
|||||||
// Otherwise, then return an instantiated Person onject with the results
|
// Otherwise, then return an instantiated Person onject with the results
|
||||||
impl From<&str> for Person {
|
impl From<&str> for Person {
|
||||||
fn from(s: &str) -> Person {
|
fn from(s: &str) -> Person {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Default::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
let splits: Vec<&str> = s.split(",").collect::<Vec<&str>>();
|
||||||
|
let name = splits[0].to_string();
|
||||||
|
let age_result = splits[1].parse::<usize>();
|
||||||
|
|
||||||
|
match age_result {
|
||||||
|
Ok(age) => Person { name, age },
|
||||||
|
Error => Default::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +60,7 @@ fn main() {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default() {
|
fn test_default() {
|
||||||
// Test that the default person is 30 year old John
|
// Test that the default person is 30 year old John
|
||||||
@ -56,6 +68,7 @@ mod tests {
|
|||||||
assert_eq!(dp.name, "John");
|
assert_eq!(dp.name, "John");
|
||||||
assert_eq!(dp.age, 30);
|
assert_eq!(dp.age, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bad_convert() {
|
fn test_bad_convert() {
|
||||||
// Test that John is returned when bad string is provided
|
// Test that John is returned when bad string is provided
|
||||||
@ -63,6 +76,7 @@ mod tests {
|
|||||||
assert_eq!(p.name, "John");
|
assert_eq!(p.name, "John");
|
||||||
assert_eq!(p.age, 30);
|
assert_eq!(p.age, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_good_convert() {
|
fn test_good_convert() {
|
||||||
// Test that "Mark,20" works
|
// Test that "Mark,20" works
|
||||||
@ -70,6 +84,7 @@ mod tests {
|
|||||||
assert_eq!(p.name, "Mark");
|
assert_eq!(p.name, "Mark");
|
||||||
assert_eq!(p.age, 20);
|
assert_eq!(p.age, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bad_age() {
|
fn test_bad_age() {
|
||||||
// Test that "Mark.twenty" will return the default person due to an error in parsing age
|
// Test that "Mark.twenty" will return the default person due to an error in parsing age
|
||||||
|
|||||||
@ -10,7 +10,6 @@ struct Person {
|
|||||||
age: usize,
|
age: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
// Steps:
|
// Steps:
|
||||||
// 1. If the length of the provided string is 0, then return an error
|
// 1. If the length of the provided string is 0, then return an error
|
||||||
// 2. Split the given string on the commas present in it
|
// 2. Split the given string on the commas present in it
|
||||||
@ -21,6 +20,18 @@ struct Person {
|
|||||||
impl FromStr for Person {
|
impl FromStr for Person {
|
||||||
type Err = String;
|
type Err = String;
|
||||||
fn from_str(s: &str) -> Result<Person, Self::Err> {
|
fn from_str(s: &str) -> Result<Person, Self::Err> {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Err("empty &str".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let splits: Vec<&str> = s.split(",").collect::<Vec<&str>>();
|
||||||
|
let name = splits[0].to_string();
|
||||||
|
let age_result = splits[1].parse::<usize>();
|
||||||
|
|
||||||
|
match age_result {
|
||||||
|
Ok(age) => Ok(Person { name, age }),
|
||||||
|
Error => Err("incorrect age".to_string()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,4 +57,4 @@ mod tests {
|
|||||||
fn missing_age() {
|
fn missing_age() {
|
||||||
"John".parse::<Person>().unwrap();
|
"John".parse::<Person>().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Basically, this is the same as From. The main difference is that this should return a Result type
|
// Basically, this is the same as From. The main difference is that this should return a Result type
|
||||||
// instead of the target type itself.
|
// instead of the target type itself.
|
||||||
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
|
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
|
||||||
use std::convert::{TryInto, TryFrom};
|
use std::convert::{TryFrom, TryInto};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Person {
|
struct Person {
|
||||||
@ -10,7 +10,6 @@ struct Person {
|
|||||||
age: usize,
|
age: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
// Your task is to complete this implementation
|
// Your task is to complete this implementation
|
||||||
// in order for the line `let p = Person::try_from("Mark,20")` to compile
|
// in order for the line `let p = Person::try_from("Mark,20")` to compile
|
||||||
// and return an Ok result of inner type Person.
|
// and return an Ok result of inner type Person.
|
||||||
@ -28,6 +27,18 @@ struct Person {
|
|||||||
impl TryFrom<&str> for Person {
|
impl TryFrom<&str> for Person {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Err("empty &str".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let splits: Vec<&str> = s.split(",").collect::<Vec<&str>>();
|
||||||
|
let name = splits[0].to_string();
|
||||||
|
let age_result = splits[1].parse::<usize>();
|
||||||
|
|
||||||
|
match age_result {
|
||||||
|
Ok(age) => Ok(Person { name, age }),
|
||||||
|
Error => Err("incorrect age".to_string()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,4 +79,4 @@ mod tests {
|
|||||||
fn test_panic_bad_age() {
|
fn test_panic_bad_age() {
|
||||||
let p = Person::try_from("Mark,twenty").unwrap();
|
let p = Person::try_from("Mark,twenty").unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,16 +2,13 @@
|
|||||||
// Please note that the `as` operator is not only used when type casting.
|
// Please note that the `as` operator is not only used when type casting.
|
||||||
// It also helps with renaming imports.
|
// It also helps with renaming imports.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
// The goal is to make sure that the division does not fail to compile
|
// The goal is to make sure that the division does not fail to compile
|
||||||
fn average(values: &[f64]) -> f64 {
|
fn average(values: &[f64]) -> f64 {
|
||||||
let total = values
|
let total = values.iter().fold(0.0, |a, b| a + *b);
|
||||||
.iter()
|
total / values.len() as f64
|
||||||
.fold(0.0, |a, b| a + b);
|
|
||||||
total / values.len()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let values = [3.5, 0.3, 13.0, 11.7];
|
let values = [3.5, 0.3, 13.0, 11.7];
|
||||||
println!("{}", average(&values));
|
println!("{}", average(&values));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
// This shopping list program isn't compiling!
|
// This shopping list program isn't compiling!
|
||||||
// Use your knowledge of generics to fix it.
|
// Use your knowledge of generics to fix it.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut shopping_list: Vec<?> = Vec::new();
|
let mut shopping_list: Vec<&str> = Vec::new();
|
||||||
shopping_list.push("milk");
|
shopping_list.push("milk");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
// This powerful wrapper provides the ability to store a positive integer value.
|
// This powerful wrapper provides the ability to store a positive integer value.
|
||||||
// Rewrite it using generics so that it supports wrapping ANY type.
|
// Rewrite it using generics so that it supports wrapping ANY type.
|
||||||
|
|
||||||
// I AM NOT DONE
|
struct Wrapper<T> {
|
||||||
struct Wrapper<u32> {
|
value: T,
|
||||||
value: u32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<u32> Wrapper<u32> {
|
impl<T> Wrapper<T> {
|
||||||
pub fn new(value: u32) -> Self {
|
pub fn new(value: T) -> Self {
|
||||||
Wrapper { value }
|
Wrapper { value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,13 +17,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn store_u32_in_wrapper() {
|
fn store_u32_in_wrapper() {
|
||||||
assert_eq!(Wrapper::new(42).value, 42);
|
assert_eq!(Wrapper::new(42).value, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn store_str_in_wrapper() {
|
fn store_str_in_wrapper() {
|
||||||
// TODO: Delete this assert and uncomment the one below once you have finished the exercise.
|
assert_eq!(Wrapper::new("Foo").value, "Foo");
|
||||||
assert!(false);
|
|
||||||
// assert_eq!(Wrapper::new("Foo").value, "Foo");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,24 @@
|
|||||||
// An imaginary magical school has a new report card generation system written in rust!
|
// An imaginary magical school has a new report card generation system written in rust!
|
||||||
// Currently the system only supports creating report cards where the student's grade
|
// Currently the system only supports creating report cards where the student's grade
|
||||||
// is represented numerically (e.g. 1.0 -> 5.5). However, the school also issues alphabetical grades
|
// is represented numerically (e.g. 1.0 -> 5.5). However, the school also issues alphabetical grades
|
||||||
// (A+ -> F-) and needs to be able to print both types of report card!
|
// (A+ -> F-) and needs to be able to print both types of report card!
|
||||||
|
|
||||||
// Make the necessary code changes to support alphabetical report cards, thereby making the second
|
// Make the necessary code changes to support alphabetical report cards, thereby making the second
|
||||||
// test pass.
|
// test pass.
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
// I AM NOT DONE
|
pub struct ReportCard<T> {
|
||||||
pub struct ReportCard {
|
pub grade: T,
|
||||||
pub grade: f32,
|
|
||||||
pub student_name: String,
|
pub student_name: String,
|
||||||
pub student_age: u8,
|
pub student_age: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReportCard {
|
impl<T: Display> ReportCard<T> {
|
||||||
pub fn print(&self) -> String {
|
pub fn print(&self) -> String {
|
||||||
format!("{} ({}) - achieved a grade of {}", &self.student_name, &self.student_age, &self.grade)
|
format!(
|
||||||
|
"{} ({}) - achieved a grade of {}",
|
||||||
|
&self.student_name, &self.student_age, &self.grade
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,21 +29,27 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn generate_numeric_report_card() {
|
fn generate_numeric_report_card() {
|
||||||
let report_card = ReportCard {
|
let report_card = ReportCard {
|
||||||
grade: 2.1,
|
grade: 2.1,
|
||||||
student_name: "Tom Wriggle".to_string(),
|
student_name: "Tom Wriggle".to_string(),
|
||||||
student_age: 12,
|
student_age: 12,
|
||||||
};
|
};
|
||||||
assert_eq!(report_card.print(), "Tom Wriggle (12) - achieved a grade of 2.1");
|
assert_eq!(
|
||||||
|
report_card.print(),
|
||||||
|
"Tom Wriggle (12) - achieved a grade of 2.1"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_alphabetic_report_card() {
|
fn generate_alphabetic_report_card() {
|
||||||
// TODO: Make sure to change the grade here after you finish the exercise.
|
// TODO: Make sure to change the grade here after you finish the exercise.
|
||||||
let report_card = ReportCard {
|
let report_card = ReportCard {
|
||||||
grade: 2.1,
|
grade: "A+".to_string(),
|
||||||
student_name: "Gary Plotter".to_string(),
|
student_name: "Gary Plotter".to_string(),
|
||||||
student_age: 11,
|
student_age: 11,
|
||||||
};
|
};
|
||||||
assert_eq!(report_card.print(), "Gary Plotter (11) - achieved a grade of A+");
|
assert_eq!(
|
||||||
|
report_card.print(),
|
||||||
|
"Gary Plotter (11) - achieved a grade of A+"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,20 +4,21 @@
|
|||||||
// somewhere. Try not to create any copies of the `numbers` Vec!
|
// somewhere. Try not to create any copies of the `numbers` Vec!
|
||||||
// Execute `rustlings hint arc1` for hints :)
|
// Execute `rustlings hint arc1` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let numbers: Vec<_> = (0..100u32).collect();
|
let numbers: Vec<_> = (0..100u32).collect();
|
||||||
let shared_numbers = // TODO
|
let shared_numbers = Arc::new(numbers);
|
||||||
let mut joinhandles = Vec::new();
|
let mut joinhandles = Vec::new();
|
||||||
|
|
||||||
for offset in 0..8 {
|
for offset in 0..8 {
|
||||||
|
let child_numbers = shared_numbers.clone();
|
||||||
|
|
||||||
joinhandles.push(thread::spawn(move || {
|
joinhandles.push(thread::spawn(move || {
|
||||||
let mut i = offset;
|
let mut i = offset;
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
|
|
||||||
while i < child_numbers.len() {
|
while i < child_numbers.len() {
|
||||||
sum += child_numbers[i];
|
sum += child_numbers[i];
|
||||||
i += 5;
|
i += 5;
|
||||||
|
|||||||
@ -5,13 +5,14 @@
|
|||||||
// Step 3. Apply the `capitalize_first` function again to a list, but try and ensure it returns a single string
|
// Step 3. Apply the `capitalize_first` function again to a list, but try and ensure it returns a single string
|
||||||
// As always, there are hints if you execute `rustlings hint iterators2`!
|
// As always, there are hints if you execute `rustlings hint iterators2`!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
use std::str::Chars;
|
||||||
|
|
||||||
pub fn capitalize_first(input: &str) -> String {
|
pub fn capitalize_first(input: &str) -> String {
|
||||||
let mut c = input.chars();
|
let mut c: Chars = input.chars();
|
||||||
match c.next() {
|
match c.next() {
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
Some(first) => first.collect::<String>() + c.as_str(),
|
Some(first) => first.to_uppercase().collect::<String>() + c.as_str(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,14 +36,14 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_iterate_string_vec() {
|
fn test_iterate_string_vec() {
|
||||||
let words = vec!["hello", "world"];
|
let words = vec!["hello", "world"];
|
||||||
let capitalized_words: Vec<String> = // TODO
|
let capitalized_words: Vec<String> = words.iter().map(|&c| capitalize_first(c)).collect();
|
||||||
assert_eq!(capitalized_words, ["Hello", "World"]);
|
assert_eq!(capitalized_words, ["Hello", "World"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterate_into_string() {
|
fn test_iterate_into_string() {
|
||||||
let words = vec!["hello", " ", "world"];
|
let words = vec!["hello", " ", "world"];
|
||||||
let capitalized_words = // TODO
|
let capitalized_words = words.iter().map(|&c| capitalize_first(c)).collect::<String>();
|
||||||
assert_eq!(capitalized_words, "Hello World");
|
assert_eq!(capitalized_words, "Hello World");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
// Execute `rustlings hint iterators3` to get some hints!
|
// Execute `rustlings hint iterators3` to get some hints!
|
||||||
// Have fun :-)
|
// Have fun :-)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum DivisionError {
|
pub enum DivisionError {
|
||||||
@ -24,7 +23,18 @@ pub struct NotDivisibleError {
|
|||||||
// This function should calculate `a` divided by `b` if `a` is
|
// This function should calculate `a` divided by `b` if `a` is
|
||||||
// evenly divisible by b.
|
// evenly divisible by b.
|
||||||
// Otherwise, it should return a suitable error.
|
// Otherwise, it should return a suitable error.
|
||||||
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {}
|
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
|
||||||
|
if b == 0 {
|
||||||
|
Err(DivisionError::DivideByZero)
|
||||||
|
} else if a % b != 0 {
|
||||||
|
Err(DivisionError::NotDivisible(NotDivisibleError {
|
||||||
|
dividend: a,
|
||||||
|
divisor: b,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Ok(a / b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@ -42,7 +52,7 @@ mod tests {
|
|||||||
divide(81, 6),
|
divide(81, 6),
|
||||||
Err(DivisionError::NotDivisible(NotDivisibleError {
|
Err(DivisionError::NotDivisible(NotDivisibleError {
|
||||||
dividend: 81,
|
dividend: 81,
|
||||||
divisor: 6
|
divisor: 6,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -58,12 +68,12 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Iterator exercises using your `divide` function
|
// Iterator exercises using your `divide` function
|
||||||
/*
|
|
||||||
#[test]
|
#[test]
|
||||||
fn result_with_list() {
|
fn result_with_list() {
|
||||||
let numbers = vec![27, 297, 38502, 81];
|
let numbers = vec![27, 297, 38502, 81];
|
||||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
||||||
let x //... Fill in here!
|
let x = division_results.collect::<Result<Vec<i32>, _>>();
|
||||||
assert_eq!(format!("{:?}", x), "Ok([1, 11, 1426, 3])");
|
assert_eq!(format!("{:?}", x), "Ok([1, 11, 1426, 3])");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +81,8 @@ mod tests {
|
|||||||
fn list_of_results() {
|
fn list_of_results() {
|
||||||
let numbers = vec![27, 297, 38502, 81];
|
let numbers = vec![27, 297, 38502, 81];
|
||||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
||||||
let x //... Fill in here!
|
let x = division_results.collect::<Vec<Result<i32, DivisionError>>>();
|
||||||
assert_eq!(format!("{:?}", x), "[Ok(1), Ok(11), Ok(1426), Ok(3)]");
|
assert_eq!(format!("{:?}", x), "[Ok(1), Ok(11), Ok(1426), Ok(3)]");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
// iterators4.rs
|
// iterators4.rs
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn factorial(num: u64) -> u64 {
|
pub fn factorial(num: u64) -> u64 {
|
||||||
// Complete this function to return factorial of num
|
// Complete this function to return factorial of num
|
||||||
@ -12,6 +11,11 @@ pub fn factorial(num: u64) -> u64 {
|
|||||||
// For the most fun don't use:
|
// For the most fun don't use:
|
||||||
// - recursion
|
// - recursion
|
||||||
// Execute `rustlings hint iterators4` for hints.
|
// Execute `rustlings hint iterators4` for hints.
|
||||||
|
|
||||||
|
match num {
|
||||||
|
1 => 1,
|
||||||
|
n => n * factorial(n - 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -5,9 +5,10 @@
|
|||||||
// of "waiting..." and the program ends without timing out when running,
|
// of "waiting..." and the program ends without timing out when running,
|
||||||
// you've got it :)
|
// you've got it :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::sync::MutexGuard;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@ -16,16 +17,18 @@ struct JobStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let status = Arc::new(JobStatus { jobs_completed: 0 });
|
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
|
||||||
let status_shared = status.clone();
|
let status_shared = status.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
for _ in 0..10 {
|
for _ in 0..100 {
|
||||||
thread::sleep(Duration::from_millis(250));
|
thread::sleep(Duration::from_millis(25));
|
||||||
status_shared.jobs_completed += 1;
|
let mut sharedJobStatus: MutexGuard<JobStatus> = status_shared.lock().unwrap();
|
||||||
|
let curr_jobs_completed: u32 = sharedJobStatus.jobs_completed as u32;
|
||||||
|
*sharedJobStatus = JobStatus { jobs_completed: curr_jobs_completed + 1 };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while status.jobs_completed < 10 {
|
while status.lock().unwrap().jobs_completed < 20 {
|
||||||
println!("waiting... ");
|
println!("waiting... {}", status.lock().unwrap().jobs_completed);
|
||||||
thread::sleep(Duration::from_millis(500));
|
thread::sleep(Duration::from_millis(25));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,14 +8,15 @@
|
|||||||
// which appends "Bar" to any object
|
// which appends "Bar" to any object
|
||||||
// implementing this trait.
|
// implementing this trait.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
trait AppendBar {
|
trait AppendBar {
|
||||||
fn append_bar(self) -> Self;
|
fn append_bar(self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppendBar for String {
|
impl AppendBar for String {
|
||||||
//Add your code here
|
|
||||||
|
|
||||||
|
fn append_bar(self) -> Self {
|
||||||
|
self + "Bar"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -41,4 +42,4 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +1,26 @@
|
|||||||
// traits2.rs
|
// traits2.rs
|
||||||
//
|
//
|
||||||
// Your task is to implement the trait
|
// Your task is to implement the trait
|
||||||
// `AppendBar' for a vector of strings.
|
// `AppendBar' for a vector of strings.
|
||||||
//
|
//
|
||||||
// To implement this trait, consider for
|
// To implement this trait, consider for
|
||||||
// a moment what it means to 'append "Bar"'
|
// a moment what it means to 'append "Bar"'
|
||||||
// to a vector of strings.
|
// to a vector of strings.
|
||||||
//
|
//
|
||||||
// No boiler plate code this time,
|
// No boiler plate code this time,
|
||||||
// you can do this!
|
// you can do this!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
trait AppendBar {
|
trait AppendBar {
|
||||||
fn append_bar(self) -> Self;
|
fn append_bar(self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Add your code here
|
impl AppendBar for Vec<String> {
|
||||||
|
fn append_bar(mut self) -> Self {
|
||||||
|
self.push("Bar".to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@ -31,5 +32,4 @@ mod tests {
|
|||||||
assert_eq!(foo.pop().unwrap(), String::from("Bar"));
|
assert_eq!(foo.pop().unwrap(), String::from("Bar"));
|
||||||
assert_eq!(foo.pop().unwrap(), String::from("Foo"));
|
assert_eq!(foo.pop().unwrap(), String::from("Foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user