mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-12 21:08:45 +00:00
Add assignment 3
This commit is contained in:
34
scripts/grade-03.sh
Executable file
34
scripts/grade-03.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -uo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# Imports library.
|
||||
BASEDIR=$(dirname "$0")
|
||||
source $BASEDIR/grade-utils.sh
|
||||
|
||||
RUNNERS=(
|
||||
"cargo"
|
||||
"cargo --release"
|
||||
"cargo_asan"
|
||||
"cargo_asan --release"
|
||||
"cargo_tsan"
|
||||
"cargo_tsan --release"
|
||||
)
|
||||
|
||||
# Lints.
|
||||
cargo fmt --check
|
||||
cargo clippy
|
||||
|
||||
# Executes test for each runner.
|
||||
for RUNNER in "${RUNNERS[@]}"; do
|
||||
echo "Running with $RUNNER..."
|
||||
|
||||
TESTS=("--lib assignment03_grade")
|
||||
if [ $(run_tests) -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
133
src/assignments/assignment03.rs
Normal file
133
src/assignments/assignment03.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
//! Assignment 3: Mastering common programming concepts (2/2).
|
||||
//!
|
||||
//! The primary goal of this assignment is to re-learn the common programming concepts in Rust, especially those in the Rust Book chapters 6, 7, 8, and 9.
|
||||
//! Please make sure you're comfortable with the concepts to proceed on to the next assignments.
|
||||
//!
|
||||
//! You should fill out the `todo!()` placeholders in such a way that `/scripts/grade-03.sh` works fine.
|
||||
//! See `assignment03_grade.rs` and `/scripts/grade-03.sh` for the test script.
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
/// Day of week.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum DayOfWeek {
|
||||
/// Sunday.
|
||||
Sun,
|
||||
/// Monday.
|
||||
Mon,
|
||||
/// Tuesday.
|
||||
Tue,
|
||||
/// Wednesday.
|
||||
Wed,
|
||||
/// Thursday.
|
||||
Thu,
|
||||
/// Friday.
|
||||
Fri,
|
||||
/// Saturday.
|
||||
Sat,
|
||||
}
|
||||
|
||||
/// The next day of week.
|
||||
///
|
||||
/// `next_weekday(Thu)` is `Fri`; and `next_weekday(Fri)` is `Mon`.
|
||||
pub fn next_weekday(day: DayOfWeek) -> DayOfWeek {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Custom option type.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum MyOption<T> {
|
||||
/// Some value of type `T`.
|
||||
MySome(T),
|
||||
/// No value.
|
||||
MyNone,
|
||||
}
|
||||
|
||||
/// Maps the inner value if the given value is `MySome`; returns `MyNone` otherwise.
|
||||
pub fn my_map<T, U, F: FnOnce(T) -> U>(v: MyOption<T>, f: F) -> MyOption<U> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Maps the inner value if the given value is `MySome`, but with a different type of function; returns `MyNone` otherwise.
|
||||
pub fn my_and_then<T, U, F: FnOnce(T) -> MyOption<U>>(v: MyOption<T>, f: F) -> MyOption<U> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Given a list of integers, returns its median (when sorted, the value in the middle position).
|
||||
///
|
||||
/// For a data set `x` of `n` elements, the median can be defined as follows:
|
||||
///
|
||||
/// - If `n` is odd, the median is `(n+1)/2`-th smallest element of `x`.
|
||||
/// - If `n` is even, the median is `(n/2)+1`-th smallest element of `x`.
|
||||
///
|
||||
/// For example, the following list of seven numbers,
|
||||
///
|
||||
/// ```
|
||||
/// vec![1, 3, 3, 6, 7, 8, 9]
|
||||
/// ```
|
||||
///
|
||||
/// has the median of 6, which is the fourth value. And for this data set of eight numbers,
|
||||
///
|
||||
/// ```
|
||||
/// vec![1, 2, 3, 4, 5, 6, 8, 9]
|
||||
/// ```
|
||||
///
|
||||
/// it has the median of 5, which is the fifth value.
|
||||
///
|
||||
/// Returns `None` if the list is empty.
|
||||
pub fn median(values: Vec<isize>) -> Option<isize> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Given a list of integers, returns its smallest mode (the value that occurs most often; a hash map will be helpful here).
|
||||
///
|
||||
/// Returns `None` if the list is empty.
|
||||
pub fn mode(values: Vec<isize>) -> Option<isize> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Converts the given string to Pig Latin. Use the rules below to translate normal English into Pig Latin.
|
||||
///
|
||||
/// 1. If a word starts with a consonant and a vowel, move the first letter of the word at the end of the word and add "ay".
|
||||
///
|
||||
/// Example: "happy" -> "appyh" + "ay" -> "appyhay"
|
||||
///
|
||||
/// 2. If a word starts with multiple consonants, move them to the end of the word and add "ay".
|
||||
///
|
||||
/// Example: "string" -> "ingstr" + "ay" -> "ingstray"
|
||||
///
|
||||
/// 3. If a word starts with a vowel, add the word "hay" at the end of the word.
|
||||
///
|
||||
/// Example: "explain" -> "explain" + "hay" -> "explainhay"
|
||||
///
|
||||
/// Keep in mind the details about UTF-8 encoding!
|
||||
///
|
||||
/// You may assume the string only contains lowercase alphabets, and it contains at least one vowel.
|
||||
pub fn piglatin(input: String) -> String {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Converts HR commands to the organization table.
|
||||
///
|
||||
/// If the commands are as follows:
|
||||
///
|
||||
/// ```
|
||||
/// vec!["Add Amir to Engineering", "Add Sally to Sales", "Remove Jeehoon from Sales", "Move Amir from Engineering to Sales"]
|
||||
/// ```
|
||||
///
|
||||
/// The return value should be:
|
||||
///
|
||||
/// ```
|
||||
/// ["Sales" -> ["Amir", "Sally"]]
|
||||
/// ```
|
||||
///
|
||||
/// - The result is a map from department to the list of its employees.
|
||||
/// - An empty department should not appear in the result.
|
||||
/// - There are three commands: "Add <person> to <department>", "Remove <person> from <department>", and "Move <person> from <department> to <department>".
|
||||
/// - If a command is not executable, then it's ignored.
|
||||
/// - There is no space in the name of the person and department.
|
||||
///
|
||||
/// See the test function for more details.
|
||||
pub fn organize(commands: Vec<String>) -> HashMap<String, HashSet<String>> {
|
||||
todo!()
|
||||
}
|
||||
168
src/assignments/assignment03_grade.rs
Normal file
168
src/assignments/assignment03_grade.rs
Normal file
@@ -0,0 +1,168 @@
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::assignment03::*;
|
||||
|
||||
#[test]
|
||||
fn test_next_weekday() {
|
||||
assert_eq!(next_weekday(DayOfWeek::Sun), DayOfWeek::Mon);
|
||||
assert_eq!(next_weekday(DayOfWeek::Mon), DayOfWeek::Tue);
|
||||
assert_eq!(next_weekday(DayOfWeek::Tue), DayOfWeek::Wed);
|
||||
assert_eq!(next_weekday(DayOfWeek::Wed), DayOfWeek::Thu);
|
||||
assert_eq!(next_weekday(DayOfWeek::Thu), DayOfWeek::Fri);
|
||||
assert_eq!(next_weekday(DayOfWeek::Fri), DayOfWeek::Mon);
|
||||
assert_eq!(next_weekday(DayOfWeek::Sat), DayOfWeek::Mon);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_my_map() {
|
||||
use MyOption::*;
|
||||
|
||||
fn len(s: &str) -> usize {
|
||||
s.len()
|
||||
}
|
||||
|
||||
fn plus_one(x: isize) -> isize {
|
||||
x + 1
|
||||
}
|
||||
|
||||
fn is_positive(x: f64) -> bool {
|
||||
x > 0.0f64
|
||||
}
|
||||
|
||||
assert_eq!(my_map(MySome("Hello, World!"), len), MySome(13));
|
||||
assert_eq!(my_map(MyNone, len), MyNone);
|
||||
|
||||
assert_eq!(my_map(MySome(1), plus_one), MySome(2));
|
||||
assert_eq!(my_map(MyNone, plus_one), MyNone);
|
||||
|
||||
assert_eq!(my_map(MySome(5.0f64), is_positive), MySome(true));
|
||||
assert_eq!(my_map(MySome(-3.0f64), is_positive), MySome(false));
|
||||
assert_eq!(my_map(MyNone::<f64>, is_positive), MyNone);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_my_and_then() {
|
||||
use MyOption::*;
|
||||
|
||||
fn plus_one(x: isize) -> MyOption<isize> {
|
||||
MySome(x + 1)
|
||||
}
|
||||
|
||||
fn none(_: isize) -> MyOption<isize> {
|
||||
MyNone
|
||||
}
|
||||
|
||||
assert_eq!(my_and_then(MySome(1), plus_one), MySome(2));
|
||||
assert_eq!(my_and_then(MySome(1), none), MyNone);
|
||||
|
||||
assert_eq!(my_and_then(MyNone, plus_one), MyNone);
|
||||
assert_eq!(my_and_then(MyNone, none), MyNone);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_median() {
|
||||
assert_eq!(median(vec![]), None);
|
||||
assert_eq!(median(vec![1]), Some(1));
|
||||
assert_eq!(median(vec![1, 2]), Some(2));
|
||||
assert_eq!(median(vec![2, 4, 5, 1, 3]), Some(3));
|
||||
assert_eq!(median(vec![2, 3, 5, 7, 11, 13]), Some(7));
|
||||
assert_eq!(median(vec![1, 3, 3, 6, 7, 8, 9]), Some(6));
|
||||
assert_eq!(median(vec![6, 7, 3, 1, 9, 3, 8]), Some(6));
|
||||
assert_eq!(median(vec![1, 2, 3, 4, 5, 6, 8, 9]), Some(5));
|
||||
assert_eq!(median(vec![3, 4, 8, 9, 1, 6, 5, 2]), Some(5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mode() {
|
||||
assert_eq!(mode(vec![]), None);
|
||||
assert_eq!(mode(vec![3]), Some(3));
|
||||
assert_eq!(mode(vec![2, 1, 2, 3]), Some(2));
|
||||
assert_eq!(mode(vec![2, 3, 1, 2, 2, 3, 3]), Some(2));
|
||||
assert_eq!(mode(vec![1, 1, 2, 2, 3, 3]), Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_piglatin() {
|
||||
assert_eq!(piglatin("pig".to_string()), "igpay".to_string());
|
||||
assert_eq!(piglatin("latin".to_string()), "atinlay".to_string());
|
||||
assert_eq!(piglatin("banana".to_string()), "ananabay".to_string());
|
||||
assert_eq!(piglatin("will".to_string()), "illway".to_string());
|
||||
assert_eq!(piglatin("butler".to_string()), "utlerbay".to_string());
|
||||
assert_eq!(piglatin("happy".to_string()), "appyhay".to_string());
|
||||
assert_eq!(piglatin("duck".to_string()), "uckday".to_string());
|
||||
assert_eq!(piglatin("me".to_string()), "emay".to_string());
|
||||
assert_eq!(piglatin("bagel".to_string()), "agelbay".to_string());
|
||||
assert_eq!(piglatin("history".to_string()), "istoryhay".to_string());
|
||||
|
||||
assert_eq!(piglatin("smile".to_string()), "ilesmay".to_string());
|
||||
assert_eq!(piglatin("string".to_string()), "ingstray".to_string());
|
||||
assert_eq!(piglatin("stupid".to_string()), "upidstay".to_string());
|
||||
assert_eq!(piglatin("glove".to_string()), "oveglay".to_string());
|
||||
assert_eq!(piglatin("trash".to_string()), "ashtray".to_string());
|
||||
assert_eq!(piglatin("floor".to_string()), "oorflay".to_string());
|
||||
assert_eq!(piglatin("store".to_string()), "orestay".to_string());
|
||||
|
||||
assert_eq!(piglatin("eat".to_string()), "eathay".to_string());
|
||||
assert_eq!(piglatin("omelet".to_string()), "omelethay".to_string());
|
||||
assert_eq!(piglatin("are".to_string()), "arehay".to_string());
|
||||
assert_eq!(piglatin("egg".to_string()), "egghay".to_string());
|
||||
assert_eq!(piglatin("explain".to_string()), "explainhay".to_string());
|
||||
assert_eq!(piglatin("ends".to_string()), "endshay".to_string());
|
||||
assert_eq!(piglatin("amulet".to_string()), "amulethay".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_organize() {
|
||||
assert_eq!(
|
||||
organize(vec![
|
||||
"Add Amir to Engineering".to_string(),
|
||||
"Add Sally to Sales".to_string(),
|
||||
"Remove Jeehoon from Sales".to_string(),
|
||||
"Move Amir from Engineering to Sales".to_string(),
|
||||
]),
|
||||
[(
|
||||
"Sales".to_string(),
|
||||
["Amir".to_string(), "Sally".to_string()].into()
|
||||
)]
|
||||
.into()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
organize(vec![
|
||||
"Add Jeehoon to Mathematics".to_string(),
|
||||
"Add Minseong to Mathematics".to_string(),
|
||||
"Add Seungmin to Computer-Science".to_string(),
|
||||
"Move Jeehoon from Mathematics to Computer-Science".to_string(),
|
||||
"Remove Minseong from Mathematics".to_string(),
|
||||
"Add Minseong to Computer-Science".to_string(),
|
||||
]),
|
||||
[(
|
||||
"Computer-Science".to_string(),
|
||||
[
|
||||
"Seungmin".to_string(),
|
||||
"Jeehoon".to_string(),
|
||||
"Minseong".to_string()
|
||||
]
|
||||
.into()
|
||||
)]
|
||||
.into()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
organize(vec![
|
||||
"Move P1 from D1 to D2".to_string(),
|
||||
"Remove P2 from D2".to_string(),
|
||||
"Add P3 to D3".to_string(),
|
||||
"Add P4 to D1".to_string(),
|
||||
"Add P3 to D4".to_string(),
|
||||
"Move P3 from D4 to D2".to_string(),
|
||||
]),
|
||||
[
|
||||
("D1".to_string(), ["P4".to_string()].into()),
|
||||
("D2".to_string(), ["P3".to_string()].into()),
|
||||
("D3".to_string(), ["P3".to_string()].into())
|
||||
]
|
||||
.into()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,3 +7,5 @@ pub mod assignment01;
|
||||
mod assignment01_grade;
|
||||
pub mod assignment02;
|
||||
mod assignment02_grade;
|
||||
pub mod assignment03;
|
||||
mod assignment03_grade;
|
||||
|
||||
Reference in New Issue
Block a user