Assignment 3 Done

This commit is contained in:
static
2024-10-03 19:14:08 +00:00
parent a05541eb3b
commit 03f169cd96
3 changed files with 150 additions and 10 deletions

View File

@@ -26,7 +26,10 @@ pub enum MyOption<T> {
/// assert_eq!(my_map(MyOption::MyNone, len), MyOption::MyNone); /// assert_eq!(my_map(MyOption::MyNone, len), MyOption::MyNone);
/// ``` /// ```
pub fn my_map<T, U, F: FnOnce(T) -> U>(v: MyOption<T>, f: F) -> MyOption<U> { pub fn my_map<T, U, F: FnOnce(T) -> U>(v: MyOption<T>, f: F) -> MyOption<U> {
todo!() match v {
MyOption::MySome(value) => MyOption::MySome(f(value)),
_ => MyOption::MyNone,
}
} }
/// Returns `MyNone` if the option is `MyNone`, otherwise calls `f` with the wrapped value and /// Returns `MyNone` if the option is `MyNone`, otherwise calls `f` with the wrapped value and
@@ -52,7 +55,10 @@ pub fn my_map<T, U, F: FnOnce(T) -> U>(v: MyOption<T>, f: F) -> MyOption<U> {
/// assert_eq!(my_and_then(MyOption::MyNone, pos_then_to_string), MyOption::MyNone); /// assert_eq!(my_and_then(MyOption::MyNone, pos_then_to_string), MyOption::MyNone);
/// ``` /// ```
pub fn my_and_then<T, U, F: FnOnce(T) -> MyOption<U>>(v: MyOption<T>, f: F) -> MyOption<U> { pub fn my_and_then<T, U, F: FnOnce(T) -> MyOption<U>>(v: MyOption<T>, f: F) -> MyOption<U> {
todo!() match v {
MyOption::MySome(value) => f(value),
_ => MyOption::MyNone,
}
} }
/// Custom operator: `option_op_or(v1, v2, f)`. If neither `v1` nor `v2` is `Some`, returns `None`. /// Custom operator: `option_op_or(v1, v2, f)`. If neither `v1` nor `v2` is `Some`, returns `None`.
@@ -76,5 +82,10 @@ pub fn my_option_op_or<T, F: FnOnce(T, T) -> T>(
v2: MyOption<T>, v2: MyOption<T>,
f: F, f: F,
) -> MyOption<T> { ) -> MyOption<T> {
todo!() match (v1, v2) {
(MyOption::MySome(value1), MyOption::MySome(value2)) => MyOption::MySome(f(value1, value2)),
(MyOption::MySome(value1), _) => MyOption::MySome(value1),
(_, MyOption::MySome(value2)) => MyOption::MySome(value2),
(_, _) => MyOption::MyNone,
}
} }

View File

@@ -27,5 +27,30 @@
/// ///
/// See `test_shell` for more examples. /// See `test_shell` for more examples.
pub fn parse_shell_command(command: &str) -> Vec<String> { pub fn parse_shell_command(command: &str) -> Vec<String> {
todo!() let mut result: Vec<String> = Vec::new();
let mut is_quote_open = false;
for word in command.split_ascii_whitespace() {
let old_is_quote_open = is_quote_open;
let content = if let Some(other) = word.strip_prefix("'") {
is_quote_open = !is_quote_open;
other
} else if let Some(other) = word.strip_suffix("'") {
is_quote_open = !is_quote_open;
other
} else {
word
};
if old_is_quote_open {
let last = result.last_mut().unwrap();
last.push(' ');
last.push_str(content);
} else {
result.push(content.to_string());
}
}
result
} }

View File

@@ -2,6 +2,7 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fmt; use std::fmt;
use std::hash::Hash;
/// Day of week. /// Day of week.
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -26,7 +27,13 @@ pub enum DayOfWeek {
/// ///
/// `next_weekday(Thu)` is `Fri`; and `next_weekday(Fri)` is `Mon`. /// `next_weekday(Thu)` is `Fri`; and `next_weekday(Fri)` is `Mon`.
pub fn next_weekday(day: DayOfWeek) -> DayOfWeek { pub fn next_weekday(day: DayOfWeek) -> DayOfWeek {
todo!() match day {
DayOfWeek::Mon => DayOfWeek::Tue,
DayOfWeek::Tue => DayOfWeek::Wed,
DayOfWeek::Wed => DayOfWeek::Thu,
DayOfWeek::Thu => DayOfWeek::Fri,
_ => DayOfWeek::Mon,
}
} }
/// Given a list of integers, returns its median (when sorted, the value in the middle position). /// Given a list of integers, returns its median (when sorted, the value in the middle position).
@@ -52,7 +59,14 @@ pub fn next_weekday(day: DayOfWeek) -> DayOfWeek {
/// ///
/// Returns `None` if the list is empty. /// Returns `None` if the list is empty.
pub fn median(values: Vec<isize>) -> Option<isize> { pub fn median(values: Vec<isize>) -> Option<isize> {
todo!() if values.is_empty() {
return None;
}
let mut values = values.to_vec();
values.sort();
Some(values[values.len() / 2])
} }
/// Given a list of integers, returns its smallest mode (the value that occurs most often; a hash /// Given a list of integers, returns its smallest mode (the value that occurs most often; a hash
@@ -60,7 +74,32 @@ pub fn median(values: Vec<isize>) -> Option<isize> {
/// ///
/// Returns `None` if the list is empty. /// Returns `None` if the list is empty.
pub fn mode(values: Vec<isize>) -> Option<isize> { pub fn mode(values: Vec<isize>) -> Option<isize> {
todo!() if values.is_empty() {
return None;
}
let mut map: HashMap<isize, i32> = HashMap::new();
for value in values {
*map.entry(value).or_insert(0) += 1;
}
let mut mode: Option<isize> = None;
let mut mode_count = 0;
for (key, value) in map {
if let Some(mode_value) = mode {
if mode_count < value || (mode_count == value && mode_value > key) {
mode = Some(key);
mode_count = value;
}
} else {
mode = Some(key);
mode_count = value;
}
}
mode
} }
/// Converts the given string to Pig Latin. Use the rules below to translate normal English into Pig /// Converts the given string to Pig Latin. Use the rules below to translate normal English into Pig
@@ -83,7 +122,25 @@ pub fn mode(values: Vec<isize>) -> Option<isize> {
/// ///
/// You may assume the string only contains lowercase alphabets, and it contains at least one vowel. /// You may assume the string only contains lowercase alphabets, and it contains at least one vowel.
pub fn piglatin(input: String) -> String { pub fn piglatin(input: String) -> String {
todo!() let is_vowel = |c: u8| matches!(c, b'a' | b'e' | b'i' | b'o' | b'u');
let input_bytes = input.as_bytes();
if is_vowel(input_bytes[0]) {
input + "hay"
} else if is_vowel(input_bytes[1]) {
let mut result = input[1..].to_string();
result.push(input_bytes[0] as char);
result.push_str("ay");
result
} else {
for i in 1..input.len() {
if is_vowel(input_bytes[i]) {
return input[i..].to_string() + &input[0..i] + "ay";
}
}
panic!();
}
} }
/// Converts HR commands to the organization table. /// Converts HR commands to the organization table.
@@ -109,7 +166,42 @@ pub fn piglatin(input: String) -> String {
/// ///
/// See the test function for more details. /// See the test function for more details.
pub fn organize(commands: Vec<String>) -> HashMap<String, HashSet<String>> { pub fn organize(commands: Vec<String>) -> HashMap<String, HashSet<String>> {
todo!() let mut result: HashMap<String, HashSet<String>> = HashMap::new();
for command in commands {
if let Some(other) = command.strip_prefix("Add ") {
let args: Vec<String> = other.split(" to ").map(String::from).collect();
_ = result
.entry(args[1].clone())
.or_default()
.insert(args[0].clone());
} else if let Some(other) = command.strip_prefix("Remove ") {
let args: Vec<String> = other.split(" from ").map(String::from).collect();
if let Some(set) = result.get_mut(&args[1]) {
_ = set.remove(&args[0]);
if set.is_empty() {
let _unused = result.remove(&args[1]);
}
}
} else if let Some(other) = command.strip_prefix("Move ") {
let args1: Vec<String> = other.split(" from ").map(String::from).collect();
let args2: Vec<String> = args1[1].split(" to ").map(String::from).collect();
if let Some(set) = result.get_mut(&args2[0]) {
if set.remove(&args1[0]) {
if set.is_empty() {
let _unused = result.remove(&args2[0]);
}
_ = result
.entry(args2[1].clone())
.or_default()
.insert(args1[0].clone());
}
}
}
}
result
} }
/// Events in a text editor. /// Events in a text editor.
@@ -130,5 +222,17 @@ pub enum TypeEvent {
/// ///
/// See the test function `test_editor` for examples. /// See the test function `test_editor` for examples.
pub fn use_editor(events: Vec<TypeEvent>) -> String { pub fn use_editor(events: Vec<TypeEvent>) -> String {
todo!() let mut result = String::new();
let mut clipboard = String::new();
for event in events {
match event {
TypeEvent::Type(value) => result.push(value),
TypeEvent::Backspace => _ = result.pop(),
TypeEvent::Copy => clipboard = result.clone(),
TypeEvent::Paste => result.push_str(&clipboard),
}
}
result
} }