mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-16 06:58:45 +00:00
assignment 1~5: fixes
- assignment05/pascal.mlw: lowered the difficulty (one more invariant given) - assignment02, 03: minor fixes & divide into sub-problems
This commit is contained in:
13
src/assignments/assignment02/mod.rs
Normal file
13
src/assignments/assignment02/mod.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
//! Assignment 2: Mastering common programming concepts (1/2).
|
||||
//!
|
||||
//! The primary goal of this assignment is to re-learn the common programming concepts in Rust, especially those in the Rust Book chapters 3 and 5.
|
||||
//! 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-02.sh` works fine.
|
||||
//! See `*_grade.rs` and `/scripts/grade-02.sh` for the test script.
|
||||
|
||||
pub mod small_problems;
|
||||
mod small_problems_grade;
|
||||
|
||||
pub mod vec_and_mat;
|
||||
mod vec_and_mat_grade;
|
||||
46
src/assignments/assignment02/small_problems.rs
Normal file
46
src/assignments/assignment02/small_problems.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
//! Small problems.
|
||||
|
||||
const FAHRENHEIT_OFFSET: f64 = 32.0;
|
||||
const FAHRENHEIT_SCALE: f64 = 5.0 / 9.0;
|
||||
|
||||
/// Converts Fahrenheit to Celsius temperature degree.
|
||||
pub fn fahrenheit_to_celsius(degree: f64) -> f64 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Capitalizes English alphabets (leaving the other characters intact).
|
||||
pub fn capitalize(input: String) -> String {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Returns the sum of the given array. (We assume the absence of integer overflow.)
|
||||
pub fn sum_array(input: &[u64]) -> u64 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Given a non-negative integer, say `n`, return the smallest integer of the form `3^m` that's greater than or equal to `n`.
|
||||
///
|
||||
/// For instance, up3(6) = 9, up3(9) = 9, up3(10) = 27. (We assume the absence of integer overflow.)
|
||||
pub fn up3(n: u64) -> u64 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Returns the greatest common divisor (GCD) of two non-negative integers. (We assume the absence of integer overflow.)
|
||||
pub fn gcd(lhs: u64, rhs: u64) -> u64 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Returns the array of nC0, nC1, nC2, ..., nCn, where nCk = n! / (k! * (n-k)!). (We assume the absence of integer overflow.)
|
||||
///
|
||||
/// Consult <https://en.wikipedia.org/wiki/Pascal%27s_triangle> for computation of binomial coefficients without integer overflow.
|
||||
pub fn chooses(n: u64) -> Vec<u64> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Returns the "zip" of two vectors.
|
||||
///
|
||||
/// For instance, `zip(vec![1, 2, 3], vec![4, 5])` equals to `vec![(1, 4), (2, 5)]`.
|
||||
/// Here, `3` is ignored because it doesn't have a partner.
|
||||
pub fn zip(lhs: Vec<u64>, rhs: Vec<u64>) -> Vec<(u64, u64)> {
|
||||
todo!()
|
||||
}
|
||||
137
src/assignments/assignment02/small_problems_grade.rs
Normal file
137
src/assignments/assignment02/small_problems_grade.rs
Normal file
@@ -0,0 +1,137 @@
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::assignments::assignment02::small_problems::*;
|
||||
|
||||
#[test]
|
||||
fn test_fahrenheit() {
|
||||
assert_eq!(fahrenheit_to_celsius(32.0), 0.0);
|
||||
assert_eq!(fahrenheit_to_celsius(212.0), 100.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_capitalize() {
|
||||
assert_eq!(
|
||||
capitalize(String::from("aAbbBcccCddddD❤한글과✓")),
|
||||
String::from("AABBBCCCCDDDDD❤한글과✓"),
|
||||
);
|
||||
assert_eq!(capitalize(String::from("Tschüß")), String::from("TSCHüß"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_up3() {
|
||||
assert_eq!(up3(0), 1);
|
||||
assert_eq!(up3(1), 1);
|
||||
assert_eq!(up3(6), 9);
|
||||
assert_eq!(up3(9), 9);
|
||||
assert_eq!(up3(10), 27);
|
||||
assert_eq!(up3(1_000_000), 1_594_323);
|
||||
assert_eq!(up3(3u64.pow(39).wrapping_add(1)), 3u64.pow(40));
|
||||
assert_eq!(up3(3u64.pow(40)), 3u64.pow(40));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gcd() {
|
||||
assert_eq!(gcd(5, 1), 1);
|
||||
assert_eq!(gcd(3, 3), 3);
|
||||
assert_eq!(gcd(2, 6), 2);
|
||||
assert_eq!(gcd(24, 18), 6);
|
||||
assert_eq!(gcd(20, 63), 1);
|
||||
assert_eq!(gcd(0, 33), 33);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sum_array() {
|
||||
assert_eq!(sum_array(&[]), 0);
|
||||
assert_eq!(sum_array(&[1]), 1);
|
||||
assert_eq!(sum_array(&[1, 2, 3, 4, 5, 100]), 115);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chooses() {
|
||||
assert_eq!(chooses(0), vec![1]);
|
||||
assert_eq!(chooses(1), vec![1, 1]);
|
||||
assert_eq!(chooses(5), vec![1, 5, 10, 10, 5, 1]);
|
||||
assert_eq!(chooses(6), vec![1, 6, 15, 20, 15, 6, 1]);
|
||||
assert_eq!(
|
||||
chooses(67),
|
||||
vec![
|
||||
1,
|
||||
67,
|
||||
2211,
|
||||
47905,
|
||||
766480,
|
||||
9657648,
|
||||
99795696,
|
||||
869648208,
|
||||
6522361560,
|
||||
42757703560,
|
||||
247994680648,
|
||||
1285063345176,
|
||||
5996962277488,
|
||||
25371763481680,
|
||||
97862516286480,
|
||||
345780890878896,
|
||||
1123787895356412,
|
||||
3371363686069236,
|
||||
9364899127970100,
|
||||
24151581961607100,
|
||||
57963796707857040,
|
||||
129728497393775280,
|
||||
271250494550621040,
|
||||
530707489338171600,
|
||||
972963730453314600,
|
||||
1673497616379701112,
|
||||
2703342303382594104,
|
||||
4105075349580976232,
|
||||
5864393356544251760,
|
||||
7886597962249166160,
|
||||
9989690752182277136,
|
||||
11923179284862717872,
|
||||
13413576695470557606,
|
||||
14226520737620288370,
|
||||
14226520737620288370,
|
||||
13413576695470557606,
|
||||
11923179284862717872,
|
||||
9989690752182277136,
|
||||
7886597962249166160,
|
||||
5864393356544251760,
|
||||
4105075349580976232,
|
||||
2703342303382594104,
|
||||
1673497616379701112,
|
||||
972963730453314600,
|
||||
530707489338171600,
|
||||
271250494550621040,
|
||||
129728497393775280,
|
||||
57963796707857040,
|
||||
24151581961607100,
|
||||
9364899127970100,
|
||||
3371363686069236,
|
||||
1123787895356412,
|
||||
345780890878896,
|
||||
97862516286480,
|
||||
25371763481680,
|
||||
5996962277488,
|
||||
1285063345176,
|
||||
247994680648,
|
||||
42757703560,
|
||||
6522361560,
|
||||
869648208,
|
||||
99795696,
|
||||
9657648,
|
||||
766480,
|
||||
47905,
|
||||
2211,
|
||||
67,
|
||||
1
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zip() {
|
||||
assert_eq!(zip(vec![1, 2], vec![4, 5]), vec![(1, 4), (2, 5)]);
|
||||
assert_eq!(zip(vec![1, 2, 3], vec![4, 5]), vec![(1, 4), (2, 5)]);
|
||||
assert_eq!(zip(vec![1, 2], vec![4, 5, 6]), vec![(1, 4), (2, 5)]);
|
||||
assert_eq!(zip(vec![], vec![4, 5]), vec![]);
|
||||
}
|
||||
}
|
||||
121
src/assignments/assignment02/vec_and_mat.rs
Normal file
121
src/assignments/assignment02/vec_and_mat.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
//! Vector and matrices.
|
||||
//!
|
||||
//! You will implement simple operations on vectors and matrices.
|
||||
|
||||
use std::ops::Mul;
|
||||
|
||||
/// 2x2 matrix of the following configuration:
|
||||
///
|
||||
/// a, b
|
||||
/// c, d
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Mat2 {
|
||||
a: u64,
|
||||
b: u64,
|
||||
c: u64,
|
||||
d: u64,
|
||||
}
|
||||
|
||||
/// 2x1 matrix of the following configuration:
|
||||
///
|
||||
/// a
|
||||
/// b
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Vec2 {
|
||||
a: u64,
|
||||
b: u64,
|
||||
}
|
||||
|
||||
impl Mat2 {
|
||||
/// Creates an identity matrix.
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
a: 1,
|
||||
b: 0,
|
||||
c: 0,
|
||||
d: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Mat2> for Mat2 {
|
||||
type Output = Mat2;
|
||||
|
||||
fn mul(self, rhs: Mat2) -> Self::Output {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Vec2> for Mat2 {
|
||||
type Output = Vec2;
|
||||
|
||||
/// Multiplies the matrix by the vector.
|
||||
fn mul(self, rhs: Vec2) -> Self::Output {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Mat2 {
|
||||
/// Calculates the power of matrix.
|
||||
fn power(self, power: u64) -> Mat2 {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Vec2 {
|
||||
/// Gets the upper value of vector.
|
||||
fn get_upper(self) -> u64 {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
/// The matrix used for calculating Fibonacci numbers.
|
||||
const FIBONACCI_MAT: Mat2 = Mat2 {
|
||||
a: 1,
|
||||
b: 1,
|
||||
c: 1,
|
||||
d: 0,
|
||||
};
|
||||
|
||||
/// The vector used for calculating Fibonacci numbers.
|
||||
const FIBONACCI_VEC: Vec2 = Vec2 { a: 1, b: 0 };
|
||||
|
||||
/// Calculates the Fibonacci number. (We assume the absence of integer overflow.)
|
||||
///
|
||||
/// Consult <https://web.media.mit.edu/~holbrow/post/calculating-fibonacci-numbers-with-matrices-and-linear-algebra/> for matrix computation of Fibonacci numbers.
|
||||
pub fn fibonacci(n: u64) -> u64 {
|
||||
(FIBONACCI_MAT.power(n) * FIBONACCI_VEC).get_upper()
|
||||
}
|
||||
|
||||
/// 2x2 floating-point matrix of the following configuration:
|
||||
///
|
||||
/// a, b
|
||||
/// c, d
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct FMat2 {
|
||||
/// row 1, column 1
|
||||
pub a: f64,
|
||||
/// row 1, column 2
|
||||
pub b: f64,
|
||||
/// row 2, column 1
|
||||
pub c: f64,
|
||||
/// row 2, column 2
|
||||
pub d: f64,
|
||||
}
|
||||
|
||||
impl FMat2 {
|
||||
/// Returns the inverse of the given matrix. (We assume the given matrix is always invertible.)
|
||||
/// HINT: https://www.mathcentre.ac.uk/resources/uploaded/sigma-matrices7-2009-1.pdf
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(
|
||||
/// Mat2 { a: 1.0, b: 1.0, c: 2.0, d: 3.0 }.inverse(),
|
||||
/// Mat2 { a: 3.0, b: -1.0, c: -2.0, d: 1.0}
|
||||
/// );
|
||||
/// ```
|
||||
pub fn inverse(self) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
60
src/assignments/assignment02/vec_and_mat_grade.rs
Normal file
60
src/assignments/assignment02/vec_and_mat_grade.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::assignments::assignment02::vec_and_mat::*;
|
||||
|
||||
#[test]
|
||||
fn test_fibonacci() {
|
||||
assert_eq!(fibonacci(0), 1);
|
||||
assert_eq!(fibonacci(1), 1);
|
||||
assert_eq!(fibonacci(2), 2);
|
||||
assert_eq!(fibonacci(3), 3);
|
||||
assert_eq!(fibonacci(4), 5);
|
||||
assert_eq!(fibonacci(5), 8);
|
||||
assert_eq!(fibonacci(6), 13);
|
||||
assert_eq!(fibonacci(7), 21);
|
||||
assert_eq!(fibonacci(50), 20365011074);
|
||||
assert_eq!(fibonacci(92), 12200160415121876738);
|
||||
}
|
||||
|
||||
// Equivalence between two floating-point matrices, as element-wise equivalence
|
||||
use std::cmp::PartialEq;
|
||||
impl PartialEq for FMat2 {
|
||||
fn eq(&self, other: &FMat2) -> bool {
|
||||
self.a == other.a && self.b == other.b && self.c == other.c && self.d == other.d
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inverse() {
|
||||
assert_eq!(
|
||||
FMat2 {
|
||||
a: 1.0,
|
||||
b: 1.0,
|
||||
c: 2.0,
|
||||
d: 3.0
|
||||
}
|
||||
.inverse(),
|
||||
FMat2 {
|
||||
a: 3.0,
|
||||
b: -1.0,
|
||||
c: -2.0,
|
||||
d: 1.0
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
FMat2 {
|
||||
a: 2.0,
|
||||
b: 3.0,
|
||||
c: 5.0,
|
||||
d: 7.0
|
||||
}
|
||||
.inverse(),
|
||||
FMat2 {
|
||||
a: -7.0,
|
||||
b: 3.0,
|
||||
c: 5.0,
|
||||
d: -2.0
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user