initial commit
This commit is contained in:
10
exercises/02_basic_calculator/00_intro/Cargo.toml
Normal file
10
exercises/02_basic_calculator/00_intro/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "intro_01"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
14
exercises/02_basic_calculator/00_intro/src/lib.rs
Normal file
14
exercises/02_basic_calculator/00_intro/src/lib.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
fn intro() -> &'static str {
|
||||
// TODO: fix me 👇
|
||||
"I'm ready to __!"
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::intro;
|
||||
|
||||
#[test]
|
||||
fn test_intro() {
|
||||
assert_eq!(intro(), "I'm ready to build a calculator in Rust!");
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/01_integers/Cargo.toml
Normal file
10
exercises/02_basic_calculator/01_integers/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "integers"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
15
exercises/02_basic_calculator/01_integers/src/lib.rs
Normal file
15
exercises/02_basic_calculator/01_integers/src/lib.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
fn compute(a: u32, b: u32) -> u32 {
|
||||
// TODO: change the line below to fix the compiler error and make the tests pass.
|
||||
let multiplier: u8 = 4;
|
||||
a + b * multiplier
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::compute;
|
||||
|
||||
#[test]
|
||||
fn case() {
|
||||
assert_eq!(compute(1, 2), 9);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/02_variables/Cargo.toml
Normal file
10
exercises/02_basic_calculator/02_variables/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "variables"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
34
exercises/02_basic_calculator/02_variables/src/lib.rs
Normal file
34
exercises/02_basic_calculator/02_variables/src/lib.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
// 👇 The lines below, starting with `///`, are called **documentation comments**.
|
||||
// They attach documentation to the item that follows them. In this case, the `speed` function.
|
||||
// If you run `cargo doc --open` from this exercise's directory, Rust will generate
|
||||
// HTML documentation from these comments and open it in your browser.
|
||||
|
||||
/// Given the start and end points of a journey, and the time it took to complete it,
|
||||
/// calculate the average speed.
|
||||
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
|
||||
// Do you need to annotate the type of `distance`? Why or why not?
|
||||
|
||||
// Don't change the line below
|
||||
distance / time_elapsed
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::speed;
|
||||
|
||||
#[test]
|
||||
fn case1() {
|
||||
assert_eq!(speed(0, 10, 10), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case2() {
|
||||
assert_eq!(speed(10, 30, 10), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case3() {
|
||||
assert_eq!(speed(10, 31, 10), 2);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/03_if_else/Cargo.toml
Normal file
10
exercises/02_basic_calculator/03_if_else/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "if_else"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
36
exercises/02_basic_calculator/03_if_else/src/lib.rs
Normal file
36
exercises/02_basic_calculator/03_if_else/src/lib.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
/// Return `12` if `n` is even,
|
||||
/// `13` if `n` is divisible by `3`,
|
||||
/// `17` otherwise.
|
||||
fn magic_number(n: u32) -> u32 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::magic_number;
|
||||
|
||||
#[test]
|
||||
fn one() {
|
||||
assert_eq!(magic_number(1), 17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two() {
|
||||
assert_eq!(magic_number(2), 12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn six() {
|
||||
assert_eq!(magic_number(6), 12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nine() {
|
||||
assert_eq!(magic_number(9), 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn high() {
|
||||
assert_eq!(magic_number(233), 17);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/04_panics/Cargo.toml
Normal file
10
exercises/02_basic_calculator/04_panics/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "panics"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
26
exercises/02_basic_calculator/04_panics/src/lib.rs
Normal file
26
exercises/02_basic_calculator/04_panics/src/lib.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
/// Given the start and end points of a journey, and the time it took to complete the journey,
|
||||
/// calculate the average speed of the journey.
|
||||
fn speed(start: u32, end: u32, time_elapsed: u32) -> u32 {
|
||||
// TODO: Panic with a custom message if `time_elapsed` is 0
|
||||
|
||||
(end - start) / time_elapsed
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::speed;
|
||||
|
||||
#[test]
|
||||
fn case1() {
|
||||
assert_eq!(speed(0, 10, 10), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// 👇 With the `#[should_panic]` annotation we can assert that we expect the code
|
||||
// under test to panic. We can also check the panic message by using `expected`.
|
||||
// This is all part of Rust's built-in test framework!
|
||||
#[should_panic(expected = "The journey took no time at all. That's impossible!")]
|
||||
fn by_zero() {
|
||||
speed(0, 10, 0);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/05_factorial/Cargo.toml
Normal file
10
exercises/02_basic_calculator/05_factorial/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "factorial"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
36
exercises/02_basic_calculator/05_factorial/src/lib.rs
Normal file
36
exercises/02_basic_calculator/05_factorial/src/lib.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
// Define a function named `factorial` that, given a non-negative integer `n`,
|
||||
// returns `n!`, the factorial of `n`.
|
||||
//
|
||||
// The factorial of `n` is defined as the product of all positive integers up to `n`.
|
||||
// For example, `5!` (read "five factorial") is `5 * 4 * 3 * 2 * 1`, which is `120`.
|
||||
// `0!` is defined to be `1`.
|
||||
//
|
||||
// We expect `factorial(0)` to return `1`, `factorial(1)` to return `1`,
|
||||
// `factorial(2)` to return `2`, and so on.
|
||||
//
|
||||
// Use only what you learned! No loops yet, so you'll have to use recursion!
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::factorial;
|
||||
|
||||
#[test]
|
||||
fn first() {
|
||||
assert_eq!(factorial(0), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn second() {
|
||||
assert_eq!(factorial(1), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn third() {
|
||||
assert_eq!(factorial(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fifth() {
|
||||
assert_eq!(factorial(5), 120);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/06_while/Cargo.toml
Normal file
10
exercises/02_basic_calculator/06_while/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "while_"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
33
exercises/02_basic_calculator/06_while/src/lib.rs
Normal file
33
exercises/02_basic_calculator/06_while/src/lib.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
// Rewrite the factorial function using a `while` loop.
|
||||
pub fn factorial(n: u32) -> u32 {
|
||||
// The `todo!()` macro is a placeholder that the compiler
|
||||
// interprets as "I'll get back to this later", thus
|
||||
// suppressing type errors.
|
||||
// It panics at runtime.
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::factorial;
|
||||
|
||||
#[test]
|
||||
fn first() {
|
||||
assert_eq!(factorial(0), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn second() {
|
||||
assert_eq!(factorial(1), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn third() {
|
||||
assert_eq!(factorial(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fifth() {
|
||||
assert_eq!(factorial(5), 120);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/07_for/Cargo.toml
Normal file
10
exercises/02_basic_calculator/07_for/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "for_"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
29
exercises/02_basic_calculator/07_for/src/lib.rs
Normal file
29
exercises/02_basic_calculator/07_for/src/lib.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
// Rewrite the factorial function using a `for` loop.
|
||||
pub fn factorial(n: u32) -> u32 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::factorial;
|
||||
|
||||
#[test]
|
||||
fn first() {
|
||||
assert_eq!(factorial(0), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn second() {
|
||||
assert_eq!(factorial(1), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn third() {
|
||||
assert_eq!(factorial(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fifth() {
|
||||
assert_eq!(factorial(5), 120);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/08_overflow/Cargo.toml
Normal file
10
exercises/02_basic_calculator/08_overflow/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "overflow"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
49
exercises/02_basic_calculator/08_overflow/src/lib.rs
Normal file
49
exercises/02_basic_calculator/08_overflow/src/lib.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
// Customize the `dev` profile to wrap around on overflow.
|
||||
// Check Cargo's documentation to find out the right syntax:
|
||||
// https://doc.rust-lang.org/cargo/reference/profiles.html
|
||||
//
|
||||
// For reasons that we'll explain later, the customization needs to be done in the `Cargo.toml`
|
||||
// at the root of the repository, not in the `Cargo.toml` of the exercise.
|
||||
|
||||
pub fn factorial(n: u32) -> u32 {
|
||||
let mut result = 1;
|
||||
for i in 1..=n {
|
||||
result *= i;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::factorial;
|
||||
|
||||
#[test]
|
||||
fn twentieth() {
|
||||
// 20! is 2432902008176640000, which is too large to fit in a u32
|
||||
// With the default dev profile, this will panic when you run `cargo test`
|
||||
// We want it to wrap around instead
|
||||
assert_eq!(factorial(20), 2_192_834_560);
|
||||
// ☝️
|
||||
// A large number literal using underscores to improve readability!
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn first() {
|
||||
assert_eq!(factorial(0), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn second() {
|
||||
assert_eq!(factorial(1), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn third() {
|
||||
assert_eq!(factorial(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fifth() {
|
||||
assert_eq!(factorial(5), 120);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/09_saturating/Cargo.toml
Normal file
10
exercises/02_basic_calculator/09_saturating/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "saturating"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
39
exercises/02_basic_calculator/09_saturating/src/lib.rs
Normal file
39
exercises/02_basic_calculator/09_saturating/src/lib.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
pub fn factorial(n: u32) -> u32 {
|
||||
let mut result = 1;
|
||||
for i in 1..=n {
|
||||
// Use saturating multiplication to stop at the maximum value of u32
|
||||
// rather than overflowing and wrapping around
|
||||
result *= i;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::factorial;
|
||||
|
||||
#[test]
|
||||
fn twentieth() {
|
||||
assert_eq!(factorial(20), u32::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn first() {
|
||||
assert_eq!(factorial(0), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn second() {
|
||||
assert_eq!(factorial(1), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn third() {
|
||||
assert_eq!(factorial(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fifth() {
|
||||
assert_eq!(factorial(5), 120);
|
||||
}
|
||||
}
|
||||
10
exercises/02_basic_calculator/10_as_casting/Cargo.toml
Normal file
10
exercises/02_basic_calculator/10_as_casting/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "as_cast"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints.rust]
|
||||
# We silence dead code warnings for the time being in order to reduce
|
||||
# compiler noise.
|
||||
# We'll re-enable them again once we explain how visibility works in Rust.
|
||||
dead_code = "allow"
|
||||
37
exercises/02_basic_calculator/10_as_casting/src/lib.rs
Normal file
37
exercises/02_basic_calculator/10_as_casting/src/lib.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
// TODO: based on what you learned in this section, replace `todo!()` with
|
||||
// the correct value after the conversion.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
#[test]
|
||||
fn u16_to_u32() {
|
||||
let v: u32 = todo!();
|
||||
assert_eq!(47u16 as u32, v);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn u8_to_i8() {
|
||||
// The compiler is smart enough to know that the value 255 cannot fit
|
||||
// inside an i8, so it'll emit a hard error. We intentionally disable
|
||||
// this guardrail to make this (bad) conversion possible.
|
||||
// The compiler is only able to pick on this because the value is a
|
||||
// literal. If we were to use a variable, the compiler wouldn't be able to
|
||||
// catch this at compile time.
|
||||
#[allow(overflowing_literals)]
|
||||
let x = { 255 as i8 };
|
||||
|
||||
// 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
|
||||
// `i8` value that is equivalent to `255` when converted to `u8`.
|
||||
let y: i8 = todo!();
|
||||
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bool_to_u8() {
|
||||
let v: u8 = todo!();
|
||||
assert_eq!(true as u8, v);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user