diff --git a/scripts/grade-09.sh b/scripts/grade-09.sh new file mode 100755 index 0000000..8120c66 --- /dev/null +++ b/scripts/grade-09.sh @@ -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 assignment09_grade") + if [ $(run_tests) -ne 0 ]; then + exit 1 + fi +done + +exit 0 diff --git a/src/assignments/assignment09.rs b/src/assignments/assignment09.rs new file mode 100644 index 0000000..56826fa --- /dev/null +++ b/src/assignments/assignment09.rs @@ -0,0 +1,154 @@ +//! Assignment 9: Iterators. +//! +//! The primary goal of this assignment is to get used to iterators. +//! +//! You should fill out the `todo!()` placeholders in such a way that `/scripts/grade-09.sh` works fine. +//! See `assignment09_grade.rs` and `/scripts/grade-09.sh` for the test script. + +use std::collections::HashMap; + +/// Returns whether the given sequence is a fibonacci sequence starts from the given sequence's first two terms. +/// +/// Returns `true` if the length of sequence is less or equal than 2. +/// +/// # Exmample +/// +/// ``` +/// 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); +/// ``` +pub fn is_fibonacci(inner: impl Iterator) -> bool { + todo!() +} + +/// Returns the sum of `f(v)` for all element `v` the given array. +/// +/// # Exmaple +/// +/// ``` +/// assert_eq!(sigma([1, 2].into_iter(), |x| x + 2), 7); +/// assert_eq!(sigma([1, 2].into_iter(), |x| x * 4), 12); +/// ``` +pub fn sigma i64>(inner: impl Iterator, f: F) -> i64 { + todo!() +} + +/// Alternate elements from three iterators until they have run out. +/// +/// # Example +/// +/// ``` +/// assert_eq!( +/// interleave3([1, 2].into_iter(), [3, 4].into_iter(), [5, 6].into_iter()), +/// vec![1, 3, 5, 2, 4, 6] +/// ); +/// ``` +pub fn interleave3( + list1: impl Iterator, + list2: impl Iterator, + list3: impl Iterator, +) -> Vec { + todo!() +} + +/// Returns mean of k smallest value's mean. +/// +/// # Example +/// +/// ``` +/// assert_eq!( +/// k_smallest_mean(vec![1, 3, 2].into_iter(), 2), +/// ((1 + 2) as f64 / 2.0) +/// ); +/// assert_eq!( +/// k_smallest_mean(vec![7, 5, 3, 6].into_iter(), 3), +/// ((3 + 5 + 6) as f64 / 3.0) +/// ); +/// ``` +pub fn k_smallest_mean(inner: impl Iterator, k: usize) -> f64 { + todo!() +} + +/// Returns mean for each class. +/// +/// # Exmaple +/// +/// ``` +/// assert_eq!( +/// calculate_mean( +/// [ +/// ("CS100".to_string(), 60), +/// ("CS200".to_string(), 60), +/// ("CS200".to_string(), 80), +/// ("CS300".to_string(), 100), +/// ] +/// .into_iter() +/// ), +/// [ +/// ("CS100".to_string(), 60.0), +/// ("CS200".to_string(), 70.0), +/// ("CS300".to_string(), 100.0) +/// ] +/// .into_iter() +/// .collect() +/// ); +/// ``` +pub fn calculate_mean(inner: impl Iterator) -> HashMap { + todo!() +} + +/// Among the cartesian product of input vectors, return the number of sets whose sum equals `n`. +/// +/// # Example +/// +/// The cartesian product of [1, 2, 3] and [2, 3] are: +/// [1, 2], [1, 3], [2, 2], [2, 3], [3, 2], [3, 3]. +/// +/// Among these sets, the number of sets whose sum is 4 is 2, which is [1, 3] and [2, 2]. +/// +/// ``` +/// 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); +/// assert_eq!(sum_is_n(vec![vec![1, 2, 3], vec![2, 3]], 6), 1); +/// assert_eq!(sum_is_n(vec![vec![1, 2, 3], vec![2, 3]], 2), 0); +/// ``` +pub fn sum_is_n(inner: Vec>, n: i64) -> usize { + todo!() +} + +/// Returns a new vector that contains the item that appears `n` times in the input vector. +/// +/// # Example +/// +/// ``` +/// 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]); +/// assert_eq!(find_count_n(vec![1, 2, 3, 4, 4], 1), vec![1, 2, 3]); +/// ``` +pub fn find_count_n(inner: Vec, n: usize) -> Vec { + todo!() +} + +/// Return the position of the median element in the vector. +/// +/// 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`. +/// +/// Please following these rules: +/// +/// - If the list is empty, returns `None`. +/// - If several elements are equally median, the position of the first of them is returned. +/// +/// # Exmaple +/// +/// ``` +/// 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)); +/// ``` +pub fn position_median(inner: Vec) -> Option { + todo!() +} diff --git a/src/assignments/assignment09_grade.rs b/src/assignments/assignment09_grade.rs new file mode 100644 index 0000000..3bd91c3 --- /dev/null +++ b/src/assignments/assignment09_grade.rs @@ -0,0 +1,202 @@ +#[cfg(test)] +mod test { + use super::super::assignment09::*; + + #[test] + fn test_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); + assert_eq!(is_fibonacci([2, 4, 6, 10, 16, 26].into_iter()), true); + assert_eq!(is_fibonacci([4, 9, 13, 22, 35].into_iter()), true); + assert_eq!(is_fibonacci([0, 0, 0, 0, 0].into_iter()), true); + assert_eq!(is_fibonacci([1, 1].into_iter()), true); + assert_eq!(is_fibonacci([1].into_iter()), true); + assert_eq!(is_fibonacci([].into_iter()), true); + + assert_eq!(is_fibonacci([1, 1, 2, 2, 3, 3].into_iter()), false); + assert_eq!(is_fibonacci([0, 0, 0, 0, 1].into_iter()), false); + assert_eq!(is_fibonacci([1, 1, 1, 1].into_iter()), false); + assert_eq!(is_fibonacci([4, 3, 2, 1].into_iter()), false); + } + + #[test] + fn test_sigma() { + assert_eq!(sigma([].into_iter(), |x: i64| x * 2), 0); + assert_eq!(sigma([1].into_iter(), |x| x * 3), 3); + assert_eq!(sigma([1, 2].into_iter(), |x| x + 2), 7); + assert_eq!(sigma([1, 2].into_iter(), |x| x * 4), 12); + assert_eq!(sigma([1, 2, 3].into_iter(), |x| x * 5), 30); + + assert_eq!( + sigma([-1.2, 3.0, 4.2, 5.8].into_iter(), |x: f64| x.floor() as i64), + 10 + ); + assert_eq!( + sigma([-1.2, 3.0, 4.2, 5.8].into_iter(), |x: f64| x.ceil() as i64), + 13 + ); + assert_eq!( + sigma([-1.2, 3.0, 4.2, 5.8].into_iter(), |x: f64| x.round() as i64), + 12 + ); + + assert_eq!( + sigma(["Hello,", "World!"].into_iter(), |x| x.len() as i64), + 12 + ); + } + + #[test] + fn test_interleave3() { + assert_eq!( + interleave3([1, 2].into_iter(), [3, 4].into_iter(), [5, 6].into_iter()), + vec![1, 3, 5, 2, 4, 6] + ); + + assert_eq!( + interleave3( + [1, 2, 3].into_iter(), + [4, 5, 6].into_iter(), + [7, 8, 9].into_iter() + ), + vec![1, 4, 7, 2, 5, 8, 3, 6, 9] + ); + + assert_eq!( + interleave3( + ["a", "b", "c"].into_iter(), + ["d", "e", "f"].into_iter(), + ["g", "h", "i"].into_iter() + ) + .into_iter() + .collect::(), + "adgbehcfi" + ); + } + + #[test] + fn test_k_smallest_man() { + assert_eq!( + k_smallest_mean(vec![1, 3, 2].into_iter(), 2), + ((1 + 2) as f64 / 2.0) + ); + assert_eq!( + k_smallest_mean(vec![5, 3, 7, 7].into_iter(), 2), + ((3 + 5) as f64 / 2.0) + ); + assert_eq!( + k_smallest_mean(vec![7, 5, 3, 6].into_iter(), 3), + ((3 + 5 + 6) as f64 / 3.0) + ); + assert_eq!( + k_smallest_mean(vec![1, 3, 2, 4, 4, 5, 6].into_iter(), 3), + ((1 + 2 + 3) as f64 / 3.0) + ); + assert_eq!(k_smallest_mean(vec![].into_iter(), 3), (0 as f64 / 3.0)); + assert_eq!( + k_smallest_mean( + vec![6, 9, 1, 14, 0, 4, 8, 7, 11, 2, 10, 3, 13, 12, 5].into_iter(), + 5 + ), + ((0 + 1 + 2 + 3 + 4) as f64 / 5.0) + ); + } + + #[test] + fn test_calculate_mean() { + assert_eq!( + calculate_mean( + [ + ("CS100".to_string(), 60), + ("CS200".to_string(), 60), + ("CS200".to_string(), 80), + ("CS300".to_string(), 100), + ] + .into_iter() + ), + [ + ("CS100".to_string(), 60.0), + ("CS200".to_string(), 70.0), + ("CS300".to_string(), 100.0) + ] + .into_iter() + .collect() + ); + + assert_eq!( + calculate_mean( + [ + ("CS220".to_string(), 60), + ("CS420".to_string(), 60), + ("CS220".to_string(), 80), + ("CS431".to_string(), 60), + ("CS420".to_string(), 80), + ("CS220".to_string(), 100) + ] + .into_iter() + ), + [ + ("CS220".to_string(), 80.0), + ("CS420".to_string(), 70.0), + ("CS431".to_string(), 60.0) + ] + .into_iter() + .collect() + ) + } + + #[test] + fn test_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); + assert_eq!(sum_is_n(vec![vec![1, 2, 3], vec![2, 3]], 6), 1); + assert_eq!(sum_is_n(vec![vec![1, 2, 3], vec![2, 3]], 2), 0); + + assert_eq!(sum_is_n(vec![(1..100).collect()], 50), 1); + + assert_eq!( + sum_is_n(vec![(1..10).collect(), (1..10).rev().collect()], 10), + 9 + ); + + assert_eq!( + sum_is_n( + vec![ + (0..10).map(|x| x * 2 + 1).collect(), + (0..20).map(|x| x * 3).collect(), + (0..30).map(|x| x * 5 + 2).collect() + ], + 53 + ), + 30 + ); + } + + // find_count_n + #[test] + fn test_find_count_n() { + assert_eq!(find_count_n(vec![], 1), vec![]); + 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]); + assert_eq!(find_count_n(vec![1, 2, 3, 4, 4], 1), vec![1, 2, 3]); + assert_eq!(find_count_n(vec![1, 3, 2, 3, 2, 3], 3), vec![3]); + assert_eq!(find_count_n(vec![1, 2, 2, 3, 3, 4], 2), vec![2, 3]); + assert_eq!(find_count_n(vec![1, 3, 2, 2, 3], 2), vec![2, 3]); + assert_eq!(find_count_n(vec![0, 2, 2, 4, 3], 0), vec![]); + assert_eq!(find_count_n(vec![1, 1, 1, 2, 2], 1), vec![]); + } + + #[test] + fn test_position_median() { + assert_eq!(position_median(Vec::::new()), None); + assert_eq!(position_median(vec![3]), Some(0)); + assert_eq!(position_median(vec![3, 3]), Some(0)); + assert_eq!(position_median(vec![3, 3, 3]), Some(0)); + assert_eq!(position_median(vec![1, 3, 3, 3]), Some(1)); + assert_eq!(position_median(vec![3, 1, 3, 3]), Some(0)); + assert_eq!(position_median(vec![1, 3, 3, 6, 7, 8, 9]), Some(3)); + assert_eq!(position_median(vec![1, 2, 3, 4, 5, 6, 8, 9]), Some(4)); + } +} diff --git a/src/assignments/mod.rs b/src/assignments/mod.rs index 3589351..d7b4c7b 100644 --- a/src/assignments/mod.rs +++ b/src/assignments/mod.rs @@ -19,3 +19,5 @@ pub mod assignment07; mod assignment07_grade; pub mod assignment08; mod assignment08_grade; +pub mod assignment09; +mod assignment09_grade;