Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: solved around 30 exercises #11

Merged
merged 1 commit into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions exercises/error_handling/errors1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@
// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

pub fn generate_nametag_text(name: String) -> Option<String> {
pub fn generate_nametag_text(name: String) -> Result<String, String> {
if name.is_empty() {
// Empty names aren't allowed.
None
Err("`name` was empty; it must be nonempty.".into())
} else {
Some(format!("Hi! My name is {}", name))
Ok(format!("Hi! My name is {}", name))
}
}

Expand Down
7 changes: 4 additions & 3 deletions exercises/error_handling/errors2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@
// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

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)
match qty {
Ok(quantity) => Ok(quantity * cost_per_item + processing_fee),
Err(e) => Err(e),
}
}

#[cfg(test)]
Expand Down
4 changes: 1 addition & 3 deletions exercises/error_handling/errors3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
// Execute `rustlings hint errors3` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

use std::num::ParseIntError;

fn main() {
let mut tokens = 100;
let pretend_user_input = "8";

let cost = total_cost(pretend_user_input)?;
let cost = total_cost(pretend_user_input).expect("failed to find integer in user input");

if cost > tokens {
println!("You can't afford that many!");
Expand Down
11 changes: 8 additions & 3 deletions exercises/error_handling/errors4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Execute `rustlings hint errors4` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);

Expand All @@ -17,7 +15,14 @@ enum CreationError {
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
// Hmm... Why is this always returning an Ok value?
Ok(PositiveNonzeroInteger(value as u64))

if value > 0 {
Ok(PositiveNonzeroInteger(value as u64))
} else if value == 0 {
Err(CreationError::Zero)
} else {
Err(CreationError::Negative)
}
}
}

Expand Down
4 changes: 1 addition & 3 deletions exercises/error_handling/errors5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@
// Execute `rustlings hint errors5` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

use std::error;
use std::fmt;
use std::num::ParseIntError;

// TODO: update the return type of `main()` to make this compile.
fn main() -> Result<(), Box<dyn ???>> {
fn main() -> Result<(), Box<dyn error::Error>> {
let pretend_user_input = "42";
let x: i64 = pretend_user_input.parse()?;
println!("output={:?}", PositiveNonzeroInteger::new(x)?);
Expand Down
8 changes: 5 additions & 3 deletions exercises/error_handling/errors6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
// Execute `rustlings hint errors6` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

use std::num::ParseIntError;

// This is a custom error type that we will be using in `parse_pos_nonzero()`.
Expand All @@ -26,12 +24,16 @@ impl ParsePosNonzeroError {
}
// TODO: add another error conversion function here.
// fn from_parseint...

fn from_parseint(err: ParseIntError) -> ParsePosNonzeroError {
ParsePosNonzeroError::ParseInt(err)
}
}

fn parse_pos_nonzero(s: &str) -> Result<PositiveNonzeroInteger, ParsePosNonzeroError> {
// TODO: change this to return an appropriate error instead of panicking
// when `parse()` returns an error.
let x: i64 = s.parse().unwrap();
let x: i64 = s.parse().map_err(ParsePosNonzeroError::from_parseint)?;
PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation)
}

Expand Down
4 changes: 1 addition & 3 deletions exercises/generics/generics1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

fn main() {
let mut shopping_list: Vec<?> = Vec::new();
let mut shopping_list: Vec<_> = Vec::new();
shopping_list.push("milk");
}
10 changes: 4 additions & 6 deletions exercises/generics/generics2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
// Execute `rustlings hint generics2` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

struct Wrapper {
value: u32,
struct Wrapper<T> {
value: T,
}

impl Wrapper {
pub fn new(value: u32) -> Self {
impl<T> Wrapper<T> {
pub fn new(value: T) -> Self {
Wrapper { value }
}
}
Expand Down
10 changes: 4 additions & 6 deletions exercises/iterators/iterators1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

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
}
24 changes: 19 additions & 5 deletions exercises/iterators/iterators2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@
// 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() {
None => String::new(),
Some(first) => ???,
Some(first) => {
let c_rest = c.as_str();
let mut capitalized_input = first.to_uppercase().to_string();
capitalized_input.push_str(c_rest);

capitalized_input
}
}
}

Expand All @@ -24,15 +28,25 @@ 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![]
let capitalized_words = words.iter().map(|word| capitalize_first(word)).collect();

return capitalized_words;
}

// Step 3.
// Apply the `capitalize_first` function again to a slice of string slices.
// Return a single string.
// ["hello", " ", "world"] -> "Hello World"
pub fn capitalize_words_string(words: &[&str]) -> String {
String::new()
String::new();

let concat_capitalized_string = words
.iter()
.cloned()
.map(|word| capitalize_first(word))
.collect();

concat_capitalized_string
}

#[cfg(test)]
Expand Down
23 changes: 17 additions & 6 deletions exercises/iterators/iterators3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -26,23 +24,36 @@ 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);
} else if a % b == 0 {
return Ok(a / b);
} else {
return Err(DivisionError::NotDivisible(NotDivisibleError {
dividend: a,
divisor: 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));

division_results.filter(|x| x.is_ok()).collect()
}

// 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)]
Expand Down
7 changes: 5 additions & 2 deletions exercises/iterators/iterators4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

pub fn factorial(num: u64) -> u64 {
// Complete this function to return the factorial of num
// Do not use:
Expand All @@ -15,6 +13,11 @@ pub fn factorial(num: u64) -> u64 {
// For an extra challenge, don't use:
// - recursion
// Execute `rustlings hint iterators4` for hints.

(1..=num)
.collect::<Vec<u64>>()
.iter()
.fold(1, |acc, x| x * acc)
}

#[cfg(test)]
Expand Down
14 changes: 10 additions & 4 deletions exercises/iterators/iterators5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -35,7 +33,10 @@ 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.into_iter()
.filter(|(key, &val)| val == value)
.collect::<Vec<_>>()
.len()
}

fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
Expand All @@ -54,7 +55,12 @@ 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!();

let count = collection
.iter()
.fold(0, |acc, col| acc + count_iterator(col, value));

count
}

#[cfg(test)]
Expand Down
4 changes: 1 addition & 3 deletions exercises/lifetimes/lifetimes1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 1 addition & 3 deletions exercises/lifetimes/lifetimes2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -17,10 +15,10 @@ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
}

fn main() {
let string2 = String::from("xyz");
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
}
println!("The longest string is '{}'", result);
Expand Down
13 changes: 7 additions & 6 deletions exercises/lifetimes/lifetimes3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Loading
Loading