mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-12 21:08:45 +00:00
Assignment 3 Done
This commit is contained in:
@@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user