Compare commits

..

7 Commits

Author SHA1 Message Date
Dylan Smith
7c3575e6ac Complete thread1 and thread2 2024-04-19 16:18:07 -04:00
Dylan Smith
f222629213 Finish thread1 2024-04-19 15:55:02 -04:00
Dylan Smith
5484d34a98 arc and moo cow 2024-04-19 15:13:03 -04:00
Dylan Smith
ad26c3a4d2 Finish reference count smart pointer 2024-04-19 14:31:51 -04:00
Dylan Smith
44e3362386 Finish Box 2024-04-19 13:56:27 -04:00
c5b8b068ea wip 2024-04-19 13:20:35 -04:00
c14f32b752 wip 2024-04-16 21:18:26 -04:00
18 changed files with 93 additions and 83 deletions

View File

@@ -8,9 +8,7 @@
// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
fn longest(x: &str, y: &str) -> &str {
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {

View File

@@ -6,8 +6,6 @@
// Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
@@ -18,9 +16,9 @@ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
fn main() {
let string1 = String::from("long string is long");
let string2 = String::from("xyz");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
}
println!("The longest string is '{}'", result);

View File

@@ -5,17 +5,18 @@
// Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
struct Book {
author: &str,
title: &str,
struct Book<'a> {
author: &'a str,
title: &'a str,
}
fn main() {
let name = String::from("Jill Smith");
let title = String::from("Fish Flying");
let book = Book { author: &name, title: &title };
let book = Book {
author: &name,
title: &title,
};
println!("{} by {}", book.title, book.author);
}

View File

@@ -10,12 +10,10 @@
// Execute `rustlings hint tests1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[cfg(test)]
mod tests {
#[test]
fn you_can_assert() {
assert!();
assert!(true);
}
}

View File

@@ -6,12 +6,10 @@
// Execute `rustlings hint tests2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[cfg(test)]
mod tests {
#[test]
fn you_can_assert_eq() {
assert_eq!();
assert_eq!(1, 1);
}
}

View File

@@ -7,8 +7,6 @@
// Execute `rustlings hint tests3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
pub fn is_even(num: i32) -> bool {
num % 2 == 0
}
@@ -19,11 +17,11 @@ mod tests {
#[test]
fn is_true_when_even() {
assert!();
assert!(is_even(2));
}
#[test]
fn is_false_when_odd() {
assert!();
assert!(!is_even(3));
}
}

View File

@@ -5,11 +5,9 @@
// Execute `rustlings hint tests4` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
struct Rectangle {
width: i32,
height: i32
height: i32,
}
impl Rectangle {
@@ -18,7 +16,7 @@ impl Rectangle {
if width <= 0 || height <= 0 {
panic!("Rectangle width and height cannot be negative!")
}
Rectangle {width, height}
Rectangle { width, height }
}
}
@@ -30,17 +28,19 @@ mod tests {
fn correct_width_and_height() {
// This test should check if the rectangle is the size that we pass into its constructor
let rect = Rectangle::new(10, 20);
assert_eq!(???, 10); // check width
assert_eq!(???, 20); // check height
assert_eq!(rect.width, 10); // check width
assert_eq!(rect.height, 20); // check height
}
#[test]
#[should_panic]
fn negative_width() {
// This test should check if program panics when we try to create rectangle with negative width
let _rect = Rectangle::new(-10, 10);
}
#[test]
#[should_panic]
fn negative_height() {
// This test should check if program panics when we try to create rectangle with negative height
let _rect = Rectangle::new(10, -10);

View File

@@ -9,18 +9,16 @@
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[test]
fn main() {
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
let mut my_iterable_fav_fruits = ???; // TODO: Step 1
let mut my_iterable_fav_fruits = my_fav_fruits.iter(); // TODO: Step 1
assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2
assert_eq!(my_iterable_fav_fruits.next(), Some(&"custard apple")); // TODO: Step 2
assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3
assert_eq!(my_iterable_fav_fruits.next(), Some(&"peach")); // TODO: Step 3
assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4
assert_eq!(my_iterable_fav_fruits.next(), None); // TODO: Step 4
}

View File

@@ -6,17 +6,18 @@
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
// Step 1.
// Complete the `capitalize_first` function.
// "hello" -> "Hello"
pub fn capitalize_first(input: &str) -> String {
let mut c = input.chars();
match c.next() {
let cap = match c.next() {
None => String::new(),
Some(first) => ???,
}
Some(first) => first.to_uppercase().to_string(),
};
let rest: String = c.collect();
format!("{cap}{rest}")
}
// Step 2.
@@ -24,7 +25,7 @@ pub fn capitalize_first(input: &str) -> String {
// Return a vector of strings.
// ["hello", "world"] -> ["Hello", "World"]
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
vec![]
words.iter().map(|f| capitalize_first(f)).collect()
}
// Step 3.
@@ -32,7 +33,7 @@ pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
// Return a single string.
// ["hello", " ", "world"] -> "Hello World"
pub fn capitalize_words_string(words: &[&str]) -> String {
String::new()
words.iter().map(|f| capitalize_first(f)).collect()
}
#[cfg(test)]

View File

@@ -9,8 +9,6 @@
// Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[derive(Debug, PartialEq, Eq)]
pub enum DivisionError {
NotDivisible(NotDivisibleError),
@@ -26,23 +24,41 @@ pub struct NotDivisibleError {
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
// Otherwise, return a suitable error.
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
todo!();
if b == 0 {
return Err(DivisionError::DivideByZero);
}
if a % b > 0 {
let e = NotDivisibleError {
dividend: a,
divisor: b,
};
return Err(DivisionError::NotDivisible(e));
}
Ok(a / b)
}
// Complete the function and return a value of the correct type so the test
// passes.
// Desired output: Ok([1, 11, 1426, 3])
fn result_with_list() -> () {
fn result_with_list() -> Result<Vec<i32>, DivisionError> {
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).unwrap())
.collect();
Ok(division_results)
}
// Complete the function and return a value of the correct type so the test
// passes.
// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)]
fn list_of_results() -> () {
fn list_of_results() -> Vec<Result<i32, DivisionError>> {
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)).collect();
division_results
}
#[cfg(test)]

View File

@@ -3,7 +3,7 @@
// Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::collections::btree_map::Range;
pub fn factorial(num: u64) -> u64 {
// Complete this function to return the factorial of num
@@ -15,6 +15,8 @@ pub fn factorial(num: u64) -> u64 {
// For an extra challenge, don't use:
// - recursion
// Execute `rustlings hint iterators4` for hints.
(1..num + 1).into_iter().fold(1, |acc, x| acc * x)
}
#[cfg(test)]

View File

@@ -11,8 +11,6 @@
// Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::collections::HashMap;
#[derive(Clone, Copy, PartialEq, Eq)]
@@ -35,7 +33,8 @@ fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
// map is a hashmap with String keys and Progress values.
// map = { "variables1": Complete, "from_str": None, ... }
todo!();
map.values().into_iter().filter(|x| **x == value).count()
}
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
@@ -54,7 +53,9 @@ fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Pr
// collection is a slice of hashmaps.
// collection = [{ "variables1": Complete, "from_str": None, ... },
// { "variables2": Complete, ... }, ... ]
todo!();
collection
.iter()
.fold(0, |acc, m| acc + count_iterator(m, value))
}
#[cfg(test)]

View File

@@ -21,19 +21,17 @@
//
// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
#![forbid(unused_imports)] // Do not change this, (or the next) line.
use std::sync::Arc;
use std::thread;
fn main() {
let numbers: Vec<_> = (0..100u32).collect();
let shared_numbers = // TODO
let shared_numbers = Arc::new(numbers); // TODO
let mut joinhandles = Vec::new();
for offset in 0..8 {
let child_numbers = // TODO
let child_numbers = Arc::clone(&shared_numbers); // TODO
joinhandles.push(thread::spawn(move || {
let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
println!("Sum of offset {} is {}", offset, sum);

View File

@@ -18,11 +18,9 @@
//
// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
#[derive(PartialEq, Debug)]
pub enum List {
Cons(i32, List),
Cons(i32, Box<List>),
Nil,
}
@@ -35,11 +33,11 @@ fn main() {
}
pub fn create_empty_list() -> List {
todo!()
List::Nil
}
pub fn create_non_empty_list() -> List {
todo!()
List::Cons(3, Box::new(List::Nil))
}
#[cfg(test)]

View File

@@ -12,8 +12,6 @@
//
// Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::borrow::Cow;
fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> {
@@ -49,6 +47,8 @@ mod tests {
let mut input = Cow::from(&slice[..]);
match abs_all(&mut input) {
// TODO
Cow::Borrowed(_) => Ok(()),
_ => Err("Expected a reference I suppose?"),
}
}
@@ -61,6 +61,8 @@ mod tests {
let mut input = Cow::from(slice);
match abs_all(&mut input) {
// TODO
Cow::Owned(_) => Ok(()),
_ => Err("Expected owned value"),
}
}
@@ -73,6 +75,8 @@ mod tests {
let mut input = Cow::from(slice);
match abs_all(&mut input) {
// TODO
Cow::Owned(_) => Ok(()),
_ => Err("Expected owned value"),
}
}
}

View File

@@ -10,8 +10,6 @@
//
// Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::rc::Rc;
#[derive(Debug)]
@@ -61,17 +59,17 @@ fn main() {
jupiter.details();
// TODO
let saturn = Planet::Saturn(Rc::new(Sun {}));
let saturn = Planet::Saturn(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
saturn.details();
// TODO
let uranus = Planet::Uranus(Rc::new(Sun {}));
let uranus = Planet::Uranus(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
uranus.details();
// TODO
let neptune = Planet::Neptune(Rc::new(Sun {}));
let neptune = Planet::Neptune(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
neptune.details();
@@ -93,12 +91,15 @@ fn main() {
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
// TODO
drop(earth);
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
// TODO
drop(venus);
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
// TODO
drop(mercury);
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
assert_eq!(Rc::strong_count(&sun), 1);

View File

@@ -8,24 +8,25 @@
// Execute `rustlings hint threads1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::thread;
use std::time::{Duration, Instant};
fn thread_func(i: u32) -> u128 {
let start = Instant::now();
thread::sleep(Duration::from_millis(250));
println!("thread {} is complete", i);
start.elapsed().as_millis()
}
fn main() {
let mut handles = vec![];
for i in 0..10 {
handles.push(thread::spawn(move || {
let start = Instant::now();
thread::sleep(Duration::from_millis(250));
println!("thread {} is complete", i);
start.elapsed().as_millis()
}));
handles.push(thread::spawn(move || thread_func(i)));
}
let mut results: Vec<u128> = vec![];
for handle in handles {
results.push(handle.join().unwrap());
// TODO: a struct is returned from thread::spawn, can you use it?
}

View File

@@ -7,9 +7,7 @@
// Execute `rustlings hint threads2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
@@ -19,7 +17,7 @@ struct JobStatus {
fn main() {
// TODO: `Arc` isn't enough if you want a **mutable** shared state
let status = Arc::new(JobStatus { jobs_completed: 0 });
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let mut handles = vec![];
for _ in 0..10 {
@@ -27,7 +25,8 @@ fn main() {
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(250));
// TODO: You must take an action before you update a shared value
status_shared.jobs_completed += 1;
let mut s = status_shared.lock().unwrap();
s.jobs_completed += 1;
});
handles.push(handle);
}
@@ -38,5 +37,5 @@ fn main() {
}
// TODO: Print the value of `JobStatus.jobs_completed`
println!("Jobs completed: {}", ???);
println!("Jobs completed: {}", status.lock().unwrap().jobs_completed);
}