nit: bruh

This commit is contained in:
2026-03-12 20:54:14 -04:00
commit 2279bea6f1
219 changed files with 4928 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
fn main() {
// Congratulations, you finished the first exercise 🎉
// As an introduction to Rustlings, the first exercise only required
// entering `n` in the terminal to go to the next exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// `println!` instead of `printline!`.
println!("Hello world!");
}

View File

@@ -0,0 +1,6 @@
fn main() {
// Declaring variables requires the `let` keyword.
let x = 5;
println!("x has the value {x}");
}

View File

@@ -0,0 +1,16 @@
fn main() {
// The easiest way to fix the compiler error is to initialize the
// variable `x`. By setting its value to an integer, Rust infers its type
// as `i32` which is the default type for integers.
let x = 42;
// But we can enforce a type different from the default `i32` by adding
// a type annotation:
// let x: u8 = 42;
if x == 10 {
println!("x is ten!");
} else {
println!("x is not ten!");
}
}

View File

@@ -0,0 +1,15 @@
#![allow(clippy::needless_late_init)]
fn main() {
// Reading uninitialized variables isn't allowed in Rust!
// Therefore, we need to assign a value first.
let x: i32 = 42;
println!("Number {x}");
// It is possible to declare a variable and initialize it later.
// But it can't be used before initialization.
let y: i32;
y = 42;
println!("Number {y}");
}

View File

@@ -0,0 +1,9 @@
fn main() {
// In Rust, variables are immutable by default.
// Adding the `mut` keyword after `let` makes the declared variable mutable.
let mut x = 3;
println!("Number {x}");
x = 5;
println!("Number {x}");
}

View File

@@ -0,0 +1,9 @@
fn main() {
let number = "T-H-R-E-E";
println!("Spell a number: {number}");
// Using variable shadowing
// https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing
let number = 3;
println!("Number plus two is: {}", number + 2);
}

View File

@@ -0,0 +1,6 @@
// The type of constants must always be annotated.
const NUMBER: u64 = 3;
fn main() {
println!("Number: {NUMBER}");
}

View File

@@ -0,0 +1,8 @@
// Some function with the name `call_me` without arguments or a return value.
fn call_me() {
println!("Hello world!");
}
fn main() {
call_me();
}

View File

@@ -0,0 +1,11 @@
// The type of function arguments must be annotated.
// Added the type annotation `u64`.
fn call_me(num: u64) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);
}
}
fn main() {
call_me(3);
}

View File

@@ -0,0 +1,10 @@
fn call_me(num: u8) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);
}
}
fn main() {
// `call_me` expects an argument.
call_me(5);
}

View File

@@ -0,0 +1,17 @@
fn is_even(num: i64) -> bool {
num % 2 == 0
}
// The return type must always be annotated.
fn sale_price(price: i64) -> i64 {
if is_even(price) {
price - 10
} else {
price - 3
}
}
fn main() {
let original_price = 51;
println!("Your sale price is {}", sale_price(original_price));
}

View File

@@ -0,0 +1,9 @@
fn square(num: i32) -> i32 {
// Removed the semicolon `;` at the end of the line below to implicitly return the result.
num * num
}
fn main() {
let answer = square(3);
println!("The square of 3 is {answer}");
}

28
solutions/03_if/if1.rs Normal file
View File

@@ -0,0 +1,28 @@
fn bigger(a: i32, b: i32) -> i32 {
if a > b { a } else { b }
}
fn main() {
// You can optionally experiment here.
}
// Don't mind this for now :)
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ten_is_bigger_than_eight() {
assert_eq!(10, bigger(10, 8));
}
#[test]
fn fortytwo_is_bigger_than_thirtytwo() {
assert_eq!(42, bigger(32, 42));
}
#[test]
fn equal_numbers() {
assert_eq!(42, bigger(42, 42));
}
}

35
solutions/03_if/if2.rs Normal file
View File

@@ -0,0 +1,35 @@
fn picky_eater(food: &str) -> &str {
if food == "strawberry" {
"Yummy!"
} else if food == "potato" {
"I guess I can eat that."
} else {
"No thanks!"
}
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn yummy_food() {
assert_eq!(picky_eater("strawberry"), "Yummy!");
}
#[test]
fn neutral_food() {
assert_eq!(picky_eater("potato"), "I guess I can eat that.");
}
#[test]
fn default_disliked_food() {
assert_eq!(picky_eater("broccoli"), "No thanks!");
assert_eq!(picky_eater("gummy bears"), "No thanks!");
assert_eq!(picky_eater("literally anything"), "No thanks!");
}
}

53
solutions/03_if/if3.rs Normal file
View File

@@ -0,0 +1,53 @@
fn animal_habitat(animal: &str) -> &str {
let identifier = if animal == "crab" {
1
} else if animal == "gopher" {
2
} else if animal == "snake" {
3
} else {
// Any unused identifier.
4
};
// Instead of such an identifier, you would use an enum in Rust.
// But we didn't get into enums yet.
if identifier == 1 {
"Beach"
} else if identifier == 2 {
"Burrow"
} else if identifier == 3 {
"Desert"
} else {
"Unknown"
}
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn gopher_lives_in_burrow() {
assert_eq!(animal_habitat("gopher"), "Burrow")
}
#[test]
fn snake_lives_in_desert() {
assert_eq!(animal_habitat("snake"), "Desert")
}
#[test]
fn crab_lives_on_beach() {
assert_eq!(animal_habitat("crab"), "Beach")
}
#[test]
fn unknown_animal() {
assert_eq!(animal_habitat("dinosaur"), "Unknown")
}
}

View File

@@ -0,0 +1,11 @@
fn main() {
let is_morning = true;
if is_morning {
println!("Good morning!");
}
let is_evening = !is_morning;
if is_evening {
println!("Good evening!");
}
}

View File

@@ -0,0 +1,21 @@
fn main() {
let my_first_initial = 'C';
if my_first_initial.is_alphabetic() {
println!("Alphabetical!");
} else if my_first_initial.is_numeric() {
println!("Numerical!");
} else {
println!("Neither alphabetic nor numeric!");
}
// Example with an emoji.
let your_character = '🦀';
if your_character.is_alphabetic() {
println!("Alphabetical!");
} else if your_character.is_numeric() {
println!("Numerical!");
} else {
println!("Neither alphabetic nor numeric!");
}
}

View File

@@ -0,0 +1,11 @@
fn main() {
// An array with 100 elements of the value 42.
let a = [42; 100];
if a.len() >= 100 {
println!("Wow, that's a big array!");
} else {
println!("Meh, I eat arrays like that for breakfast.");
panic!("Array not big enough, more elements needed");
}
}

View File

@@ -0,0 +1,23 @@
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
#[test]
fn slice_out_of_array() {
let a = [1, 2, 3, 4, 5];
// 0 1 2 3 4 <- indices
// -------
// |
// +--- slice
// Note that the upper index 4 is excluded.
let nice_slice = &a[1..4];
assert_eq!([2, 3, 4], nice_slice);
// The upper index can be included by using the syntax `..=` (with `=` sign)
let nice_slice = &a[1..=3];
assert_eq!([2, 3, 4], nice_slice);
}
}

View File

@@ -0,0 +1,8 @@
fn main() {
let cat = ("Furry McFurson", 3.5);
// Destructuring the tuple.
let (name, age) = cat;
println!("{name} is {age} years old");
}

View File

@@ -0,0 +1,16 @@
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
#[test]
fn indexing_tuple() {
let numbers = (1, 2, 3);
// Tuple indexing syntax.
let second = numbers.1;
assert_eq!(second, 2, "This is not the 2nd number in the tuple!");
}
}

View File

@@ -0,0 +1,23 @@
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
let a = [10, 20, 30, 40]; // Array
// Used the `vec!` macro.
let v = vec![10, 20, 30, 40];
(a, v)
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_array_and_vec_similarity() {
let (a, v) = array_and_vec();
assert_eq!(a, *v);
}
}

View File

@@ -0,0 +1,55 @@
fn vec_loop(input: &[i32]) -> Vec<i32> {
let mut output = Vec::new();
for element in input {
output.push(2 * element);
}
output
}
fn vec_map_example(input: &[i32]) -> Vec<i32> {
// An example of collecting a vector after mapping.
// We map each element of the `input` slice to its value plus 1.
// If the input is `[1, 2, 3]`, the output is `[2, 3, 4]`.
input.iter().map(|element| element + 1).collect()
}
fn vec_map(input: &[i32]) -> Vec<i32> {
// We will dive deeper into iterators, but for now, this is all what you
// had to do!
// Advanced note: This method is more efficient because it automatically
// preallocates enough capacity. This can be done manually in `vec_loop`
// using `Vec::with_capacity(input.len())` instead of `Vec::new()`.
input.iter().map(|element| 2 * element).collect()
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec_loop() {
let input = [2, 4, 6, 8, 10];
let ans = vec_loop(&input);
assert_eq!(ans, [4, 8, 12, 16, 20]);
}
#[test]
fn test_vec_map_example() {
let input = [1, 2, 3];
let ans = vec_map_example(&input);
assert_eq!(ans, [2, 3, 4]);
}
#[test]
fn test_vec_map() {
let input = [2, 4, 6, 8, 10];
let ans = vec_map(&input);
assert_eq!(ans, [4, 8, 12, 16, 20]);
}
}

View File

@@ -0,0 +1,25 @@
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
// ^^^ added
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics1() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
// `vec0` can't be accessed anymore because it is moved to `fill_vec`.
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
}

View File

@@ -0,0 +1,28 @@
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics2() {
let vec0 = vec![22, 44, 66];
// Cloning `vec0` so that the clone is moved into `fill_vec`, not `vec0`
// itself.
let vec1 = fill_vec(vec0.clone());
assert_eq!(vec0, [22, 44, 66]);
assert_eq!(vec1, [22, 44, 66, 88]);
}
}

View File

@@ -0,0 +1,22 @@
fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
// ^^^ added
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics3() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec1, [22, 44, 66, 88]);
}
}

View File

@@ -0,0 +1,19 @@
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
#[test]
fn move_semantics4() {
let mut x = Vec::new();
let y = &mut x;
// `y` used here.
y.push(42);
// The mutable reference `y` is not used anymore,
// therefore a new reference can be created.
let z = &mut x;
z.push(13);
assert_eq!(x, [42, 13]);
}
}

View File

@@ -0,0 +1,23 @@
#![allow(clippy::ptr_arg)]
// Borrows instead of taking ownership.
// It is recommended to use `&str` instead of `&String` here. But this is
// enough for now because we didn't handle strings yet.
fn get_char(data: &String) -> char {
data.chars().last().unwrap()
}
// Takes ownership instead of borrowing.
fn string_uppercase(mut data: String) {
data = data.to_uppercase();
println!("{data}");
}
fn main() {
let data = "Rust is great!".to_string();
get_char(&data);
string_uppercase(data);
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

6
solutions/README.md Normal file
View File

@@ -0,0 +1,6 @@
# Official Rustlings solutions
Before you finish an exercise, its solution file will only contain an empty `main` function.
The content of this file will be automatically replaced by the actual solution once you finish the exercise.
Note that these solutions are often only _one possibility_ to solve an exercise.

View File

@@ -0,0 +1,30 @@
// Mary is buying apples. The price of an apple is calculated as follows:
// - An apple costs 2 rustbucks.
// - However, if Mary buys more than 40 apples, the price of each apple in the
// entire order is reduced to only 1 rustbuck!
fn calculate_price_of_apples(n_apples: u64) -> u64 {
if n_apples > 40 {
n_apples
} else {
2 * n_apples
}
}
fn main() {
// You can optionally experiment here.
}
// Don't change the tests!
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn verify_test() {
assert_eq!(calculate_price_of_apples(35), 70);
assert_eq!(calculate_price_of_apples(40), 80);
assert_eq!(calculate_price_of_apples(41), 41);
assert_eq!(calculate_price_of_apples(65), 65);
}
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}

View File

@@ -0,0 +1,4 @@
fn main() {
// DON'T EDIT THIS SOLUTION FILE!
// It will be automatically filled after you finish the exercise.
}