Compare commits

...

17 Commits

Author SHA1 Message Date
d3b4c0d653 solution to exercise 03_03 2024-06-19 15:03:51 +02:00
8b78ea3a83 solution to exercise 03_02 2024-06-19 14:56:36 +02:00
0e5cdc6d10 solution to exercise 03_01 2024-06-19 14:46:00 +02:00
1d876eff10 solution to exercise 03_00 2024-06-19 14:41:41 +02:00
dfcb9736b2 solution to exercise 02_10 2024-06-17 11:31:06 +02:00
c1e7c3fadd solution to exercise 02_09 2024-06-17 11:22:25 +02:00
978a99b00d solution to exercise 02_08 2024-06-17 11:15:21 +02:00
34189d212e solution to exercise 02_07 2024-06-17 10:59:03 +02:00
9d1869fc9c solution to exercise 02_06 2024-06-17 10:53:22 +02:00
3e56cf1287 solution to exercise 02_05 2024-06-15 21:01:03 +02:00
f91cc0089a solution to exercise 02_04 2024-06-13 17:04:21 +02:00
211f23cea4 solution to exercise 02_03 2024-06-13 16:55:06 +02:00
1e516bf0a5 solution to exercise 02_02 2024-06-13 16:46:44 +02:00
03a0a77394 solution to exercise 02_01 2024-06-13 16:40:40 +02:00
bb27bfad41 solution to exercise 02_00 2024-06-13 16:33:07 +02:00
4d12facc2f solution to exercise 01 2024-06-12 17:12:56 +02:00
1251a6c1b1 solution to exercise 00 2024-06-12 17:06:43 +02:00
17 changed files with 65 additions and 17 deletions

View File

@@ -1,3 +1,6 @@
[workspace] [workspace]
members = ["exercises/*/*", "helpers/common", "helpers/mdbook-exercise-linker", "helpers/ticket_fields"] members = ["exercises/*/*", "helpers/common", "helpers/mdbook-exercise-linker", "helpers/ticket_fields"]
resolver = "2" resolver = "2"
[profile.dev]
overflow-checks = false

View File

@@ -17,7 +17,7 @@
// You can also find solutions to all exercises in the `solutions` git branch. // You can also find solutions to all exercises in the `solutions` git branch.
fn greeting() -> &'static str { fn greeting() -> &'static str {
// TODO: fix me 👇 // TODO: fix me 👇
"I'm ready to __!" "I'm ready to learn Rust!"
} }
// Your solutions will be automatically verified by a set of tests. // Your solutions will be automatically verified by a set of tests.

View File

@@ -3,7 +3,7 @@
// partner in this course and it'll often guide you in the right direction! // partner in this course and it'll often guide you in the right direction!
// //
// The input parameters should have the same type of the return type. // The input parameters should have the same type of the return type.
fn compute(a, b) -> u32 { fn compute(a: u32, b: u32) -> u32 {
// Don't touch the function body. // Don't touch the function body.
a + b * 2 a + b * 2
} }

View File

@@ -1,6 +1,6 @@
fn intro() -> &'static str { fn intro() -> &'static str {
// TODO: fix me 👇 // TODO: fix me 👇
"I'm ready to __!" "I'm ready to build a calculator in Rust!"
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -1,6 +1,6 @@
fn compute(a: u32, b: u32) -> u32 { fn compute(a: u32, b: u32) -> u32 {
// TODO: change the line below to fix the compiler error and make the tests pass. // TODO: change the line below to fix the compiler error and make the tests pass.
a + b * 4u8 a + b * 4u32
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -8,7 +8,7 @@
pub fn speed(start: u32, end: u32, time_elapsed: u32) -> u32 { pub fn speed(start: u32, end: u32, time_elapsed: u32) -> u32 {
// TODO: define a variable named `distance` with the right value to get tests to pass // TODO: define a variable named `distance` with the right value to get tests to pass
// Do you need to annotate the type of `distance`? Why or why not? // Do you need to annotate the type of `distance`? Why or why not?
let distance: u32 = end - start;
// Don't change the line below // Don't change the line below
distance / time_elapsed distance / time_elapsed
} }

View File

@@ -1,6 +1,6 @@
/// Return `true` if `n` is even, `false` otherwise. /// Return `true` if `n` is even, `false` otherwise.
fn is_even(n: u32) -> bool { fn is_even(n: u32) -> bool {
todo!() n % 2 == 0
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -2,7 +2,9 @@
/// calculate the average speed of the journey. /// calculate the average speed of the journey.
fn speed(start: u32, end: u32, time_elapsed: u32) -> u32 { fn speed(start: u32, end: u32, time_elapsed: u32) -> u32 {
// TODO: Panic with a custom message if `time_elapsed` is 0 // TODO: Panic with a custom message if `time_elapsed` is 0
if time_elapsed == 0 {
panic!("The journey took no time at all, that's impossible!");
}
(end - start) / time_elapsed (end - start) / time_elapsed
} }

View File

@@ -9,6 +9,13 @@
// `factorial(2)` to return `2`, and so on. // `factorial(2)` to return `2`, and so on.
// //
// Use only what you learned! No loops yet, so you'll have to use recursion! // Use only what you learned! No loops yet, so you'll have to use recursion!
fn factorial(n: u16) -> u16 {
if n == 0 {
1
} else {
n * factorial(n - 1)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@@ -4,7 +4,13 @@ pub fn factorial(n: u32) -> u32 {
// interprets as "I'll get back to this later", thus // interprets as "I'll get back to this later", thus
// suppressing type errors. // suppressing type errors.
// It panics at runtime. // It panics at runtime.
todo!() let mut result: u32 = 1; // base case
let mut i: u32 = 1;
while i <= n {
result *= i;
i += 1;
}
result
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -1,6 +1,10 @@
// Rewrite the factorial function using a `for` loop. // Rewrite the factorial function using a `for` loop.
pub fn factorial(n: u32) -> u32 { pub fn factorial(n: u32) -> u32 {
todo!() let mut result: u32 = 1; // base case
for i in 2..=n {
result *= i;
}
result
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -1,9 +1,9 @@
pub fn factorial(n: u32) -> u32 { pub fn factorial(n: u32) -> u32 {
let mut result = 1; let mut result: u32 = 1;
for i in 1..=n { for i in 1..=n {
// Use saturating multiplication to stop at the maximum value of u32 // Use saturating multiplication to stop at the maximum value of u32
// rather than overflowing and wrapping around // rather than overflowing and wrapping around
result *= i; result = result.saturating_mul(i);
} }
result result
} }

View File

@@ -6,7 +6,7 @@ mod tests {
#[test] #[test]
fn u16_to_u32() { fn u16_to_u32() {
let v: u32 = todo!(); let v: u32 = 47;
assert_eq!(47u16 as u32, v); assert_eq!(47u16 as u32, v);
} }
@@ -24,14 +24,14 @@ mod tests {
// You could solve this by using exactly the same expression as above, // You could solve this by using exactly the same expression as above,
// but that would defeat the purpose of the exercise. Instead, use a genuine // but that would defeat the purpose of the exercise. Instead, use a genuine
// `i8` value that is equivalent to `255` when converted from `u8`. // `i8` value that is equivalent to `255` when converted from `u8`.
let y: i8 = todo!(); let y: i8 = -1;
assert_eq!(x, y); assert_eq!(x, y);
} }
#[test] #[test]
fn bool_to_u8() { fn bool_to_u8() {
let v: u8 = todo!(); let v: u8 = 1;
assert_eq!(true as u8, v); assert_eq!(true as u8, v);
} }
} }

View File

@@ -1,6 +1,6 @@
fn intro() -> &'static str { fn intro() -> &'static str {
// TODO: fix me 👇 // TODO: fix me 👇
"I'm ready to __!" "I'm ready to start modelling a software ticket!"
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -4,6 +4,16 @@
// //
// It should also have a method named `is_available` that returns a `true` if the quantity is // It should also have a method named `is_available` that returns a `true` if the quantity is
// greater than 0, otherwise `false`. // greater than 0, otherwise `false`.
struct Order {
price: u8,
quantity: u8,
}
impl Order {
fn is_available(self) -> bool {
self.quantity > 0
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@@ -17,7 +17,22 @@ impl Ticket {
// as well as some `String` methods. Use the documentation of Rust's standard library // as well as some `String` methods. Use the documentation of Rust's standard library
// to find the most appropriate options -> https://doc.rust-lang.org/std/string/struct.String.html // to find the most appropriate options -> https://doc.rust-lang.org/std/string/struct.String.html
fn new(title: String, description: String, status: String) -> Self { fn new(title: String, description: String, status: String) -> Self {
todo!(); if status != "To-Do" && status != "In Progress" && status != "Done" {
panic!("Only `To-Do`, `In Progress`, and `Done` statuses are allowed")
}
if title.is_empty() {
panic!("Title cannot be empty")
}
if description.is_empty() {
panic!("Description cannot be empty")
}
if title.len() > 50 {
panic!("Title cannot be longer than 50 bytes")
}
if description.len() > 500 {
panic!("Description cannot be longer than 500 bytes")
}
Self { Self {
title, title,
description, description,

View File

@@ -1,6 +1,7 @@
mod helpers { mod helpers {
// TODO: Make this code compile, either by adding a `use` statement or by using // TODO: Make this code compile, either by adding a `use` statement or by using
// the appropriate path to refer to the `Ticket` struct. // the appropriate path to refer to the `Ticket` struct.
use super::Ticket;
fn create_todo_ticket(title: String, description: String) -> Ticket { fn create_todo_ticket(title: String, description: String) -> Ticket {
Ticket::new(title, description, "To-Do".into()) Ticket::new(title, description, "To-Do".into())