mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-15 06:28:46 +00:00
Add assignment 10
This commit is contained in:
33
scripts/grade-10.sh
Executable file
33
scripts/grade-10.sh
Executable 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 assignment10_grade")
|
||||||
|
if [ $(run_tests) -ne 0 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
||||||
119
src/assignments/assignment10.rs
Normal file
119
src/assignments/assignment10.rs
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
//! Assignment 10: Iterators (2/2).
|
||||||
|
//!
|
||||||
|
//! 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-10.sh` works fine.
|
||||||
|
//! See `assignment10_grade.rs` and `/scripts/grade-10.sh` for the test script.
|
||||||
|
|
||||||
|
use itertools::*;
|
||||||
|
|
||||||
|
/// Returns the pairs of `(i, j)` where `i < j` and `inner[i] > inner[j]` in increasing order.
|
||||||
|
///
|
||||||
|
/// For example, the inversions of `[3, 5, 1, 2, 4]` is `[(0, 2), (0, 3), (1, 2), (1, 3), (1, 4)]` because as follows:
|
||||||
|
///
|
||||||
|
/// - `0 < 2`, `inner[0] = 3 > 1 = inner[2]`
|
||||||
|
/// - `0 < 3`, `inner[0] = 3 > 2 = inner[3]`
|
||||||
|
/// - `1 < 2`, `inner[1] = 5 > 1 = inner[2]`
|
||||||
|
/// - `1 < 3`, `inner[1] = 5 > 2 = inner[3]`
|
||||||
|
/// - `1 < 4`, `inner[1] = 5 > 4 = inner[4]`
|
||||||
|
///
|
||||||
|
/// Consult <https://en.wikipedia.org/wiki/Inversion_(discrete_mathematics)> for more details of inversion.
|
||||||
|
pub fn inversion<T: Ord>(inner: Vec<T>) -> Vec<(usize, usize)> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a node of tree data structure.
|
||||||
|
///
|
||||||
|
/// Consult <https://en.wikipedia.org/wiki/Tree_(data_structure)> for more details on tree data structure.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Node<T> {
|
||||||
|
/// Non-leaf node
|
||||||
|
///
|
||||||
|
/// It contains `(the name of node, list of child nodes)`.
|
||||||
|
NonLeaf((T, Vec<Node<T>>)),
|
||||||
|
/// Leaf node
|
||||||
|
///
|
||||||
|
/// It contains the name of node.
|
||||||
|
Leaf(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Traverses the tree in preorder.
|
||||||
|
///
|
||||||
|
/// The algorithm for preorder traversal is as follows:
|
||||||
|
///
|
||||||
|
/// 1. Visit the root.
|
||||||
|
/// 2. If the root is a leaf node, end the traverse.
|
||||||
|
/// 3. If the root is a non-leaf node, traverse each subtree from the child nodes.
|
||||||
|
///
|
||||||
|
/// For example, the result of preorder traversal for the following tree
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// 1
|
||||||
|
/// /|\
|
||||||
|
/// 2 3 4
|
||||||
|
/// /| /|\
|
||||||
|
/// 5 6 7 8 9
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// which can be represented as
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// Node::NonLeaf((
|
||||||
|
/// 1,
|
||||||
|
/// vec![
|
||||||
|
/// Node::NonLeaf((2, vec![Node::Leaf(5), Node::Leaf(6)])),
|
||||||
|
/// Node::Leaf(3),
|
||||||
|
/// Node::NonLeaf((4, vec![Node::Leaf(7), Node::Leaf(8), Node::Leaf(9)])),
|
||||||
|
/// ]
|
||||||
|
/// ))
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// is `1 -> 2 -> 5 -> 6 -> 3 -> 4 -> 7 -> 8 -> 9`.
|
||||||
|
pub fn traverse_preorder<T>(root: Node<T>) -> Vec<T> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// File
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum File {
|
||||||
|
/// Directory
|
||||||
|
///
|
||||||
|
/// It contains `(name of directory, list of files under the directory)`
|
||||||
|
///
|
||||||
|
/// The size of a directory is the sum of the sizes of its sub-files.
|
||||||
|
Directory(String, Vec<File>),
|
||||||
|
|
||||||
|
/// Data
|
||||||
|
///
|
||||||
|
/// It contains `(name of data, size of data)`
|
||||||
|
Data(String, usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a file, summarize all subfiles and sizes in ascending order of size.
|
||||||
|
///
|
||||||
|
/// - Its behaviour is the same as the `du | sort -h` command on Linux.
|
||||||
|
/// - If the file size is the same, sort it by name.
|
||||||
|
/// - Assume that there are no duplicate file names.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// Input:
|
||||||
|
///
|
||||||
|
/// ```txt
|
||||||
|
/// root (Directory)
|
||||||
|
/// |
|
||||||
|
/// |__a (Directory)
|
||||||
|
/// | |__a1 (Data, size: 1)
|
||||||
|
/// | |__a2 (Data, size: 3)
|
||||||
|
/// |
|
||||||
|
/// |__b (Directory)
|
||||||
|
/// | |__b1 (Data, size: 3)
|
||||||
|
/// | |__b2 (Data, size: 15)
|
||||||
|
/// |
|
||||||
|
/// |__c (Data, size: 8)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Output: `[("a1", 1), ("a2", 3), ("b1", 3), ("a", 4), ("c", 8), ("b2", 15), ("b", 18), ("root", 30)]`
|
||||||
|
pub fn du_sort(root: &File) -> Vec<(&str, usize)> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
123
src/assignments/assignment10_grade.rs
Normal file
123
src/assignments/assignment10_grade.rs
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::super::assignment10::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_inversion() {
|
||||||
|
assert_eq!(inversion(vec![3, 5, 4]), vec![(1, 2)]);
|
||||||
|
assert_eq!(inversion(vec!["c", "a", "b", "d"]), vec![(0, 1), (0, 2)]);
|
||||||
|
assert_eq!(
|
||||||
|
inversion(vec![2, 5, 4, 6, 3, 1]),
|
||||||
|
vec![
|
||||||
|
(0, 5),
|
||||||
|
(1, 2),
|
||||||
|
(1, 4),
|
||||||
|
(1, 5),
|
||||||
|
(2, 4),
|
||||||
|
(2, 5),
|
||||||
|
(3, 4),
|
||||||
|
(3, 5),
|
||||||
|
(4, 5)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_traverse_preorder() {
|
||||||
|
let root = Node::NonLeaf((
|
||||||
|
1,
|
||||||
|
vec![
|
||||||
|
Node::NonLeaf((2, vec![Node::Leaf(5), Node::Leaf(6)])),
|
||||||
|
Node::Leaf(3),
|
||||||
|
Node::NonLeaf((4, vec![Node::Leaf(7), Node::Leaf(8), Node::Leaf(9)])),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(traverse_preorder(root), vec![1, 2, 5, 6, 3, 4, 7, 8, 9]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_du_sort() {
|
||||||
|
let rootfile = File::Directory(
|
||||||
|
"root".to_string(),
|
||||||
|
vec![
|
||||||
|
File::Directory(
|
||||||
|
"a".to_string(),
|
||||||
|
vec![
|
||||||
|
File::Data("a1".to_string(), 1),
|
||||||
|
File::Data("a2".to_string(), 3),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
File::Directory(
|
||||||
|
"b".to_string(),
|
||||||
|
vec![
|
||||||
|
File::Data("b1".to_string(), 3),
|
||||||
|
File::Data("b2".to_string(), 15),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
File::Data("c".to_string(), 8),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
du_sort(&rootfile),
|
||||||
|
vec![
|
||||||
|
("a1", 1),
|
||||||
|
("a2", 3),
|
||||||
|
("b1", 3),
|
||||||
|
("a", 4),
|
||||||
|
("c", 8),
|
||||||
|
("b2", 15),
|
||||||
|
("b", 18),
|
||||||
|
("root", 1 + 3 + 3 + 15 + 8)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
let rootfile = File::Directory(
|
||||||
|
"root".to_string(),
|
||||||
|
vec![
|
||||||
|
File::Directory(
|
||||||
|
"a".to_string(),
|
||||||
|
vec![
|
||||||
|
File::Data("a1".to_string(), 1),
|
||||||
|
File::Data("a2".to_string(), 3),
|
||||||
|
File::Directory(
|
||||||
|
"a3".to_string(),
|
||||||
|
vec![
|
||||||
|
File::Data("a31".to_string(), 1),
|
||||||
|
File::Data("a32".to_string(), 3),
|
||||||
|
File::Data("a33".to_string(), 6),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
File::Directory(
|
||||||
|
"b".to_string(),
|
||||||
|
vec![
|
||||||
|
File::Data("b1".to_string(), 3),
|
||||||
|
File::Data("b2".to_string(), 15),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
File::Data("c".to_string(), 16),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
du_sort(&rootfile),
|
||||||
|
vec![
|
||||||
|
("a1", 1),
|
||||||
|
("a31", 1),
|
||||||
|
("a2", 3),
|
||||||
|
("a32", 3),
|
||||||
|
("b1", 3),
|
||||||
|
("a33", 6),
|
||||||
|
("a3", 10),
|
||||||
|
("a", 14),
|
||||||
|
("b2", 15),
|
||||||
|
("c", 16),
|
||||||
|
("b", 18),
|
||||||
|
("root", 48)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,3 +22,5 @@ pub mod assignment08;
|
|||||||
mod assignment08_grade;
|
mod assignment08_grade;
|
||||||
pub mod assignment09;
|
pub mod assignment09;
|
||||||
mod assignment09_grade;
|
mod assignment09_grade;
|
||||||
|
pub mod assignment10;
|
||||||
|
mod assignment10_grade;
|
||||||
|
|||||||
Reference in New Issue
Block a user