Add assignments 12 and 13

This commit is contained in:
Seungmin Jeon
2022-12-04 15:37:02 +09:00
parent 98694dd0da
commit a44b420ea3
11 changed files with 288 additions and 7 deletions

33
scripts/grade-12.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/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.
run_linters || exit 1
# Executes test for each runner.
for RUNNER in "${RUNNERS[@]}"; do
echo "Running with $RUNNER..."
TESTS=("--lib assignment12_grade")
if [ $(run_tests) -ne 0 ]; then
exit 1
fi
done
exit 0

33
scripts/grade-13.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/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.
run_linters || exit 1
# Executes test for each runner.
for RUNNER in "${RUNNERS[@]}"; do
echo "Running with $RUNNER..."
TESTS=("--lib assignment13_grade")
if [ $(run_tests) -ne 0 ]; then
exit 1
fi
done
exit 0

View File

@@ -50,6 +50,8 @@ pub enum MyOption<T> {
/// Converts an `MyOption<String>` into an `MyOption<usize>`, consuming the original:
///
/// ```
/// use cs220::assignments::assignment03::{my_map, MyOption};
///
/// fn len(s: String) -> usize {
/// s.len()
/// }
@@ -68,6 +70,8 @@ pub fn my_map<T, U, F: FnOnce(T) -> U>(v: MyOption<T>, f: F) -> MyOption<U> {
/// # Examples
///
/// ```
/// use cs220::assignments::assignment03::{MyOption, my_and_then};
///
/// fn pos_then_to_string(x: isize) -> MyOption<String> {
/// if x > 0 {
/// MyOption::MySome(x.to_string())
@@ -93,13 +97,13 @@ pub fn my_and_then<T, U, F: FnOnce(T) -> MyOption<U>>(v: MyOption<T>, f: F) -> M
///
/// For example, the following list of seven numbers,
///
/// ```
/// ```ignore
/// 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,
///
/// ```
/// ```ignore
/// vec![1, 2, 3, 4, 5, 6, 8, 9]
/// ```
///
@@ -142,13 +146,13 @@ pub fn piglatin(input: String) -> String {
///
/// If the commands are as follows:
///
/// ```
/// ```ignore
/// vec!["Add Amir to Engineering", "Add Sally to Sales", "Remove Jeehoon from Sales", "Move Amir from Engineering to Sales"]
/// ```
///
/// The return value should be:
///
/// ```
/// ```ignore
/// ["Sales" -> ["Amir", "Sally"]]
/// ```
///

View File

@@ -91,7 +91,7 @@ impl Semiring for f64 {
///
/// For example, polynomial `x^2 + 5x + 6` is represented in `Polynomial<u64>` as follows:
///
/// ```
/// ```ignore
/// Polynomial {
/// coefficients: {
/// 2: 1,

View File

@@ -16,6 +16,8 @@ use itertools::*;
/// # Exmample
///
/// ```
/// use cs220::assignments::assignment09::is_fibonacci;
///
/// assert_eq!(is_fibonacci([1, 1, 2, 3, 5, 8, 13].into_iter()), true);
/// assert_eq!(is_fibonacci([1, 1, 2, 3, 5, 8, 14].into_iter()), false);
/// ```
@@ -28,6 +30,8 @@ pub fn is_fibonacci(inner: impl Iterator<Item = i64>) -> bool {
/// # Exmaple
///
/// ```
/// use cs220::assignments::assignment09::sigma;
///
/// assert_eq!(sigma([1, 2].into_iter(), |x| x + 2), 7);
/// assert_eq!(sigma([1, 2].into_iter(), |x| x * 4), 12);
/// ```
@@ -42,6 +46,8 @@ pub fn sigma<T, F: Fn(T) -> i64>(inner: impl Iterator<Item = T>, f: F) -> i64 {
/// # Example
///
/// ```
/// use cs220::assignments::assignment09::interleave3;
///
/// assert_eq!(
/// interleave3([1, 2].into_iter(), [3, 4].into_iter(), [5, 6].into_iter()),
/// vec![1, 3, 5, 2, 4, 6]
@@ -60,6 +66,8 @@ pub fn interleave3<T>(
/// # Example
///
/// ```
/// use cs220::assignments::assignment09::k_smallest_mean;
///
/// assert_eq!(
/// k_smallest_mean(vec![1, 3, 2].into_iter(), 2),
/// ((1 + 2) as f64 / 2.0)
@@ -78,6 +86,8 @@ pub fn k_smallest_mean(inner: impl Iterator<Item = i64>, k: usize) -> f64 {
/// # Exmaple
///
/// ```
/// use cs220::assignments::assignment09::calculate_mean;
///
/// assert_eq!(
/// calculate_mean(
/// [
@@ -111,6 +121,8 @@ pub fn calculate_mean(inner: impl Iterator<Item = (String, i64)>) -> HashMap<Str
/// Among these sets, the number of sets whose sum is 4 is 2, which is [1, 3] and [2, 2].
///
/// ```
/// use cs220::assignments::assignment09::sum_is_n;
///
/// assert_eq!(sum_is_n(vec![vec![1, 2, 3], vec![2, 3]], 3), 1);
/// assert_eq!(sum_is_n(vec![vec![1, 2, 3], vec![2, 3]], 4), 2);
/// assert_eq!(sum_is_n(vec![vec![1, 2, 3], vec![2, 3]], 5), 2);
@@ -126,6 +138,8 @@ pub fn sum_is_n(inner: Vec<Vec<i64>>, n: i64) -> usize {
/// # Example
///
/// ```
/// use cs220::assignments::assignment09::find_count_n;
///
/// assert_eq!(find_count_n(vec![1, 2], 1), vec![1, 2]);
/// assert_eq!(find_count_n(vec![1, 3, 3], 1), vec![1]);
/// assert_eq!(find_count_n(vec![1, 3, 3], 2), vec![3]);
@@ -150,6 +164,8 @@ pub fn find_count_n(inner: Vec<usize>, n: usize) -> Vec<usize> {
/// # Exmaple
///
/// ```
/// use cs220::assignments::assignment09::position_median;
///
/// assert_eq!(position_median(vec![1, 3, 3, 6, 7, 8, 9]), Some(3));
/// assert_eq!(position_median(vec![1, 3, 3, 3]), Some(1));
/// ```

View File

@@ -47,7 +47,7 @@ pub enum Node<T> {
///
/// For example, the result of preorder traversal for the following tree
///
/// ```
/// ```ignore
/// 1
/// /|\
/// 2 3 4
@@ -57,7 +57,7 @@ pub enum Node<T> {
///
/// which can be represented as
///
/// ```
/// ```ignore
/// Node::NonLeaf((
/// 1,
/// vec![

View File

@@ -0,0 +1,33 @@
#![allow(single_use_lifetimes)]
//! Assignment 12: Concurrency.
//!
//! The primary goal of this assignment is to get used to concurrency.
//!
//! You should fill out the `todo!()` placeholders in such a way that `/scripts/grade-12.sh` works fine.
//! See `assignment12_grade.rs` and `/scripts/grade-12.sh` for the test script.
use std::sync::mpsc::{Receiver, RecvError, Sender};
use std::thread;
use etrace::*;
/// The "pong" function (read the test script to figure out what it should do).
pub fn pong(rx1: &mut Receiver<u32>, tx2: &mut Sender<u32>) -> bool {
todo!()
}
/// Executes the given functions (f1, f2) and returns the results.
pub fn use_scoped_thread<'scope, 'env, T1, T2, F1, F2>(
s: &'scope thread::Scope<'scope, 'env>,
f1: F1,
f2: F2,
) -> (T1, T2)
where
T1: Send + 'scope,
T2: Send + 'scope,
F1: Send + FnOnce() -> T1 + 'scope,
F2: Send + FnOnce() -> T2 + 'scope,
{
todo!()
}

View File

@@ -0,0 +1,44 @@
#[cfg(test)]
mod test {
use super::super::assignment12::*;
use std::sync::mpsc::channel;
use std::thread;
#[test]
fn test_ping_pong() {
let (tx1, mut rx1) = channel();
let (mut tx2, rx2) = channel();
let thread_ping = thread::spawn(move || {
for i in 0..100 {
tx1.send(i).unwrap();
let x = rx2.recv().unwrap();
assert_eq!(x, i + 1);
}
});
let thread_pong = thread::spawn(move || while pong(&mut rx1, &mut tx2) {});
thread_ping.join().unwrap();
thread_pong.join().unwrap();
}
#[test]
fn test_scoped_thread() {
for i in 0..100 {
let v = (0..i).collect::<Vec<u32>>();
thread::scope(|s| {
let (r1, r2) = use_scoped_thread(
s,
|| v.iter().sum::<u32>(),
|| v.windows(2).map(|x| x[0] * x[1]).sum::<u32>(),
);
assert_eq!(r1, v.iter().sum());
assert_eq!(r2, v.windows(2).map(|x| x[0] * x[1]).sum());
});
}
}
}

View File

@@ -0,0 +1,47 @@
//! Assignment 13: Parallelism.
//!
//! The primary goal of this assignment is to get used to data parallelism.
//!
//! You should fill out the `todo!()` placeholders in such a way that `/scripts/grade-13.sh` works fine.
//! See `assignment13_grade.rs` and `/scripts/grade-13.sh` for the test script.
use rayon::prelude::*;
/// Returns the sum of `f(v)` for all element `v` the given array.
///
/// # Exmaple
///
/// ```
/// use cs220::assignments::assignment13::sigma;
/// use rayon::iter::IntoParallelIterator;
///
/// assert_eq!(sigma([1, 2].into_par_iter(), |x| x + 2), 7);
/// assert_eq!(sigma([1, 2].into_par_iter(), |x| x * 4), 12);
/// ```
pub fn sigma<T, F: Fn(T) -> i64 + Sync + Send>(
inner: impl ParallelIterator<Item = T>,
f: F,
) -> i64 {
todo!()
}
/// Alternate elements from three iterators until they have run out.
///
/// # Example
///
/// ```
/// use cs220::assignments::assignment13::interleave3;
/// use rayon::iter::IntoParallelIterator;
///
/// assert_eq!(
/// interleave3([1, 2].into_par_iter(), [3, 4].into_par_iter(), [5, 6].into_par_iter()),
/// vec![1, 3, 5, 2, 4, 6]
/// );
/// ```
pub fn interleave3<T: Send>(
list1: impl IndexedParallelIterator<Item = T>,
list2: impl IndexedParallelIterator<Item = T>,
list3: impl IndexedParallelIterator<Item = T>,
) -> Vec<T> {
todo!()
}

View File

@@ -0,0 +1,67 @@
#[cfg(test)]
mod test {
use super::super::assignment13::*;
use rayon::prelude::IntoParallelIterator;
#[test]
fn test_sigma() {
assert_eq!(sigma([].into_par_iter(), |x: i64| x * 2), 0);
assert_eq!(sigma([1].into_par_iter(), |x| x * 3), 3);
assert_eq!(sigma([1, 2].into_par_iter(), |x| x + 2), 7);
assert_eq!(sigma([1, 2].into_par_iter(), |x| x * 4), 12);
assert_eq!(sigma([1, 2, 3].into_par_iter(), |x| x * 5), 30);
assert_eq!(
sigma([-1.2, 3.0, 4.2, 5.8].into_par_iter(), |x: f64| x.floor()
as i64),
10
);
assert_eq!(
sigma([-1.2, 3.0, 4.2, 5.8].into_par_iter(), |x: f64| x.ceil()
as i64),
13
);
assert_eq!(
sigma([-1.2, 3.0, 4.2, 5.8].into_par_iter(), |x: f64| x.round()
as i64),
12
);
assert_eq!(
sigma(["Hello,", "World!"].into_par_iter(), |x| x.len() as i64),
12
);
}
#[test]
fn test_interleave3() {
assert_eq!(
interleave3(
[1, 2].into_par_iter(),
[3, 4].into_par_iter(),
[5, 6].into_par_iter()
),
vec![1, 3, 5, 2, 4, 6]
);
assert_eq!(
interleave3(
[1, 2, 3].into_par_iter(),
[4, 5, 6].into_par_iter(),
[7, 8, 9].into_par_iter()
),
vec![1, 4, 7, 2, 5, 8, 3, 6, 9]
);
assert_eq!(
interleave3(
["a", "b", "c"].into_par_iter(),
["d", "e", "f"].into_par_iter(),
["g", "h", "i"].into_par_iter()
)
.into_iter()
.collect::<String>(),
"adgbehcfi"
);
}
}

View File

@@ -26,3 +26,7 @@ pub mod assignment10;
mod assignment10_grade;
pub mod assignment11;
mod assignment11_grade;
pub mod assignment12;
mod assignment12_grade;
pub mod assignment13;
mod assignment13_grade;