From a56ee76d584a6c79dad5910b3d586feb0569cbe1 Mon Sep 17 00:00:00 2001 From: Seungmin Jeon Date: Tue, 15 Nov 2022 00:10:00 +0900 Subject: [PATCH] Add assignment 10 --- scripts/grade-10.sh | 33 +++++++ src/assignments/assignment10.rs | 119 +++++++++++++++++++++++++ src/assignments/assignment10_grade.rs | 123 ++++++++++++++++++++++++++ src/assignments/mod.rs | 2 + 4 files changed, 277 insertions(+) create mode 100755 scripts/grade-10.sh create mode 100644 src/assignments/assignment10.rs create mode 100644 src/assignments/assignment10_grade.rs diff --git a/scripts/grade-10.sh b/scripts/grade-10.sh new file mode 100755 index 0000000..a221be6 --- /dev/null +++ b/scripts/grade-10.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 assignment10_grade") + if [ $(run_tests) -ne 0 ]; then + exit 1 + fi +done + +exit 0 diff --git a/src/assignments/assignment10.rs b/src/assignments/assignment10.rs new file mode 100644 index 0000000..37c8449 --- /dev/null +++ b/src/assignments/assignment10.rs @@ -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 for more details of inversion. +pub fn inversion(inner: Vec) -> Vec<(usize, usize)> { + todo!() +} + +/// Represents a node of tree data structure. +/// +/// Consult for more details on tree data structure. +#[derive(Debug)] +pub enum Node { + /// Non-leaf node + /// + /// It contains `(the name of node, list of child nodes)`. + NonLeaf((T, Vec>)), + /// 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(root: Node) -> Vec { + 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), + + /// 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!() +} diff --git a/src/assignments/assignment10_grade.rs b/src/assignments/assignment10_grade.rs new file mode 100644 index 0000000..61ad501 --- /dev/null +++ b/src/assignments/assignment10_grade.rs @@ -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) + ] + ); + } +} diff --git a/src/assignments/mod.rs b/src/assignments/mod.rs index aa38ded..a616d50 100644 --- a/src/assignments/mod.rs +++ b/src/assignments/mod.rs @@ -22,3 +22,5 @@ pub mod assignment08; mod assignment08_grade; pub mod assignment09; mod assignment09_grade; +pub mod assignment10; +mod assignment10_grade;