#![allow(unused)]
fn main() {
//! Use a tuple index operator to access the second element of
//! `numbers`.
#[test]
fn indexing_tuple() {
let numbers = (1, 2, 3);
// Create a variable holding the second number of the tuple.
let second = numbers.1;
assert_eq!(2, second, "This is not the second number in the tuple!")
}
}
//! Destructure the `cat` tuple so that the println will work.
fn main() {
let cat = ("Furry McFurson", 3.5);
let (name, age) = cat;
println!("{} is {} years old.", name, age); // Don't change this line
}
//! Mutate the tuple so that the test passes
fn swap_tuple((x, y): (i32, i32)) -> (i32, i32) {
(y, x)
}
fn main() {
let mut tup = (2, 5);
// TODO mutate the second element in `tup`
tup.1 = 4;
assert_eq!(swap_tuple(tup), (4, 2));
}
//! Ok, here are a bunch of values-- some are `String`s, some are string slices:
//! `&str`s. Your task is to call one of these two functions on each value
//! depending on what you think each value is. That is, add either `string_slice`
//! or `string` before the parentheses on each line. There may be multiple
//! solutions.
fn string_slice(arg: &str) {
println!("{}", arg);
}
fn string(arg: String) {
println!("{}", arg);
}
fn main() {
string_slice("blue");
string("red".to_string());
string(String::from("hi"));
string("rust is fun!".to_owned());
string("nice weather".into());
string(format!("Interpolation {}", "Station"));
string_slice(&String::from("abc")[0..1]);
string_slice(" hello there ".trim());
string("Happy Monday!".to_string().replace("Mon", "Tues"));
string("mY sHiFt KeY iS sTiCkY".to_lowercase());
}
#![allow(unused)]
fn main() {
//! Step 1: fix `vec_loop` function's definition to allow using
//! `v.iter_mut()`.
//!
//! Step 2: complete the loop so that each number in the Vec is
//! multiplied by 2.
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
for elem in v.iter_mut() {
// TODO: Fill this up so that each element in the Vec `v` is
// multiplied by 2. Hint: mutating the referent of `&mut i32`
// requires a dereference.
*elem *= 2;
}
v
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec_loop() {
let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
let ans = vec_loop(v.clone());
assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
}
}
}
#![allow(unused)]
fn main() {
//! Your task is to take a nice slice into `a` so that the test passes.
#[test]
fn slice_out_of_array() {
let a = [1, 2, 3, 4, 5];
let nice_slice = &a[1..4];
assert_eq!([2, 3, 4], nice_slice)
}
}
#![allow(unused)]
fn main() {
//! Your task is to create a `Vec` which holds the exact same elements as in the
//! array `a`. Make me compile and pass the test! Use the `vec!` macro:
//! https://doc.rust-lang.org/std/macro.vec.html
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
let a = [10, 20, 30, 40];
let v = vec![10, 20, 30, 40];
(a, v)
}
#[test]
fn test_array_and_vec_similarity() {
let (a, v) = array_and_vec();
assert_eq!(a, v[..]);
}
}
//! Note: if your editor complains about `try_into`, it only works on
//! edition 2021 which `otarustlings` supports, so don't mind the
//! error.
fn make_mult_table(num: i32) -> [String; 10] {
// The _ here tells Rust that it needs to figure it out so that
// you don't need to. The Vec is required as collect can return
// any collection that implements the FromIterator trait.
let vec: Vec<_> = (0..10)
.into_iter()
.map(|i| format!("{i} * {num} = {}", i as i32 * num))
.collect();
vec.try_into().expect("vector to have exactly 10 elements")
}
fn main() {
let a = make_mult_table(3);
// TODO create a reference to the correct element
let nine = &a[3];
println!("the array is {:#?}", a);
assert_eq!(nine, "3 * 3 = 9");
}
//! You can't change anything except adding or removing references `&`
fn main() {
let data = "Rust is great!".to_string();
get_char(&data);
string_uppercase(data);
}
// TODO Should not take ownership
fn get_char(data: &String) -> char {
data.chars().last().unwrap()
}
// TODO Should take ownership
fn string_uppercase(mut data: String) {
data = data.to_uppercase();
println!("{}", data);
}
//! Your task is to fix the function `third`. Hint: the issue is not
//! related to lifetimes.
//!
//! Note: The exercises use strings in array because they are not
//! cheap to copy (unlike integers for example).
// TODO fix "lifetime" errors
fn third(a: &[String]) -> (&[String], &str) {
(a, &a[2])
}
// Don't edit the following code
fn eat(s: String) {
println!("{}", s);
}
fn main() {
let a = [
"first".to_string(),
"second".to_string(),
"third".to_string(),
"fourth".to_string(),
];
let (b, third) = third(&a);
println!("{}", third);
eat(a
.into_iter()
.nth(1)
.expect("a to contain at least two elements"));
}
//! Your task is to mutate the point in main to pass the assertion
/// A struct is a statically sized collection of data with keys and values.
struct Point {
x: i32,
y: i32,
}
fn display_point(point: &Point) {
println!("{}, {}", point.x, point.y);
}
fn main() {
let mut point = Point {
x: 3,
y: -5,
};
// TODO mutate point's x-coordinate
point.x = 6;
display_point(&point);
assert_eq!(point.x, 6);
}
#![allow(unused)]
fn main() {
//! Your task is to capitalize the first letter/character in `string`. Search
//! the Rust standard library documentation for `str::chars`. Note that a String
//! has all the methods of str because of the `Deref` trait. Don't be afraid to
//! search more information online
fn capitalize_first(string: &mut String) {
// First we take the first character, which can be multiple bytes, but one
// UTF-8 character only (max 4 bytes). We do nothing and return if there is
// no first character.
// For example with "firm" the bytes are
// string: [u8] = EF AC 81 72 6d
// ^^^^^^^^-fi r m
if let Some(first) = string.chars().next() {
// the first character 'fi'
// first: char = 01 fb 00 00
// Next we create a string from the characters (yes there can be
// multiple) which are now in uppercase.
let first_uppercase = first.to_uppercase().collect::<String>();
// first_uppercase: [u8] = 46 49
// F I
let mut first_chars = first_uppercase.chars();
if let Some(first_char) = first_chars.next() {
// Next we take the first character and join it with the rest of
// the characters after converting them to lowercase
let first_capitalized = std::iter::once(first_char)
.chain(first_chars.map(char::to_lowercase).flatten())
.collect::<String>();
// Finally we remove the first `len_utf8` bytes from the string and
// prepend with the bytes from `first_uppercase`.
// string.replace_range(..first.len_utf8(), &first_uppercase);
// Behind the scenes the string is converted to vector and spliced with
// the new data `first_uppercase`
// https://doc.rust-lang.org/std/vec/struct.Vec.html#method.splice
string.replace_range(..first.len_utf8(), &first_capitalized);
// and the string is
// string: [u8] = 46 69 72 6d
// F i r m
}
}
}
#[test]
fn letters() {
let mut string = "testing".to_string();
capitalize_first(&mut string);
assert_eq!(string, "Testing");
}
#[test]
fn numbers() {
let mut string = "1234".to_string();
capitalize_first(&mut string);
assert_eq!(string, "1234");
}
#[test]
fn special() {
let mut string = "山".to_string();
capitalize_first(&mut string);
assert_eq!(string, "山");
}
#[test]
fn emoji() {
let mut string = "❤".to_string();
capitalize_first(&mut string);
assert_eq!(string, "❤");
}
#[test]
fn sigma() {
let mut string = "Σ".to_string();
capitalize_first(&mut string);
assert_eq!(string, "Σ");
}
// The hard one
#[test]
fn ligatures() {
let mut string = "firm".to_string();
capitalize_first(&mut string);
assert_eq!(string, "Firm");
}
}
//! This is a bonus exercise.
//!
//! Your task is to find the right number to rotate the VecDeque by. You are
//! only allowed to change the argument to `rotate_right`
use std::collections::VecDeque;
fn make_uncontiguous_vecdeq() -> VecDeque<i32> {
let mut vd: VecDeque<_> = (1..=5).chain(1..=5).collect();
// TODO rotate the deque until both slices are equal
vd.rotate_right(5);
vd
}
fn main() {
let vd = make_uncontiguous_vecdeq();
let (head, tail) = vd.as_slices();
assert_eq!(head, tail);
}
//! This is a bonus exercise (hard)
use std::collections::HashMap;
fn make_vec() -> Vec<(&'static str, i32)> {
vec![("a",1),("b",2),("c",3)]
}
fn make_hashmap() -> HashMap<&'static str, i32> {
let mut hm = HashMap::new();
hm.insert("d", 4);
hm.insert("e", 5);
hm.insert("f", 6);
hm
}
// TODO fill in the blanks
fn print_dyn_iter(iter: &mut dyn Iterator<Item = (&str, i32)>) {
for (key, value) in iter {
println!("{key} - {value}")
}
}
fn main() {
let mut v = make_vec().into_iter();
let mut hm = make_hashmap().into_iter();
print_dyn_iter(&mut v);
assert_eq!(v.next(), None);
print_dyn_iter(&mut hm);
assert_eq!(hm.next(), None);
}
//! This is a bonus exercise (hard)
//!
//! Your task is to make the main function not panic. You can only change code
//! inside main.
//!
//! Part 1: swap the values of v and hm safely with something from
//! https://doc.rust-lang.org/std/mem/index.html
//!
//! Part 2: fix the next problem ¯\_(°ペ)_/¯
use std::any::Any;
use std::collections::HashMap;
fn make_something() -> Box<dyn Any> {
Box::new(vec![("a", 1), ("b", 2), ("c", 3)])
}
fn make_something_else() -> Box<dyn Any> {
let mut hm = HashMap::new();
hm.insert("d", 4);
hm.insert("e", 5);
hm.insert("f", 6);
Box::new(hm)
}
fn check_type_vec(any: &mut dyn Any) {
if let Some(vec) = any.downcast_ref::<Vec<(&str, i32)>>() {
println!("is vector");
} else {
panic!("TypeError: Vec expected");
}
}
fn check_type_hashmap(any: &mut dyn Any) {
if let Some(hm) = any.downcast_ref::<HashMap<&str, i32>>() {
println!("is hashmap");
} else {
panic!("TypeError: HashMap expected");
}
}
// You can only edit code in the main function
fn main() {
let mut v: Box<dyn Any> = make_something();
let mut hm: Box<dyn Any> = make_something_else();
std::mem::swap(&mut v, &mut hm);
// Reborrow is needed to get a reference to the data inside the box
check_type_hashmap(&mut *v);
check_type_vec(&mut *hm);
}