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);
/// ```
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
@@ -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);
/// ```
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`.
@@ -76,5 +82,10 @@ pub fn my_option_op_or<T, F: FnOnce(T, T) -> T>(
v2: MyOption<T>,
f: F,
) -> 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.
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::fmt;
use std::hash::Hash;
/// Day of week.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -26,7 +27,13 @@ pub enum DayOfWeek {
///
/// `next_weekday(Thu)` is `Fri`; and `next_weekday(Fri)` is `Mon`.
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).
@@ -52,7 +59,14 @@ pub fn next_weekday(day: DayOfWeek) -> DayOfWeek {
///
/// Returns `None` if the list is empty.
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
@@ -60,7 +74,32 @@ pub fn median(values: Vec<isize>) -> Option<isize> {
///
/// Returns `None` if the list is empty.
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
@@ -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.
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.
@@ -109,7 +166,42 @@ pub fn piglatin(input: String) -> String {
///
/// See the test function for more details.
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.
@@ -130,5 +222,17 @@ pub enum TypeEvent {
///
/// See the test function `test_editor` for examples.
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
}