mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-15 06:28:46 +00:00
Add assignment 6
This commit is contained in:
34
scripts/grade-06.sh
Executable file
34
scripts/grade-06.sh
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#!/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.
|
||||||
|
cargo fmt --check
|
||||||
|
cargo clippy
|
||||||
|
|
||||||
|
# Executes test for each runner.
|
||||||
|
for RUNNER in "${RUNNERS[@]}"; do
|
||||||
|
echo "Running with $RUNNER..."
|
||||||
|
|
||||||
|
TESTS=("--lib assignment06_grade")
|
||||||
|
if [ $(run_tests) -ne 0 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
||||||
153
src/assignments/assignment06.rs
Normal file
153
src/assignments/assignment06.rs
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
//! Assignment 6: Mastering advanced types.
|
||||||
|
//!
|
||||||
|
//! The primary goal of this assignment is to understand generics, traits, and lifetimes.
|
||||||
|
//!
|
||||||
|
//! You should fill out the `todo!()` placeholders in such a way that `/scripts/grade-06.sh` works fine.
|
||||||
|
//! See `assignment06_grade.rs` and `/scripts/grade-06.sh` for the test script.
|
||||||
|
|
||||||
|
use std::{collections::HashMap, fmt::Debug};
|
||||||
|
|
||||||
|
/// Semiring.
|
||||||
|
///
|
||||||
|
/// Consult <https://en.wikipedia.org/wiki/Semiring>.
|
||||||
|
pub trait Semiring: Debug + Clone + PartialEq {
|
||||||
|
/// Additive identity.
|
||||||
|
fn zero() -> Self;
|
||||||
|
/// Multiplicative identity.
|
||||||
|
fn one() -> Self;
|
||||||
|
/// Addition operation.
|
||||||
|
fn add(&self, rhs: &Self) -> Self;
|
||||||
|
/// Multiplication operation.
|
||||||
|
fn mul(&self, rhs: &Self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts integer to semiring value.
|
||||||
|
pub fn from_usize<T: Semiring>(value: usize) -> T {
|
||||||
|
let mut result = T::zero();
|
||||||
|
let one = T::one();
|
||||||
|
|
||||||
|
for _ in 0..value {
|
||||||
|
result = T::add(&result, &one);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Semiring for u64 {
|
||||||
|
fn zero() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn one() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&self, rhs: &Self) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mul(&self, rhs: &Self) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Semiring for i64 {
|
||||||
|
fn zero() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn one() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&self, rhs: &Self) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mul(&self, rhs: &Self) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Semiring for f64 {
|
||||||
|
fn zero() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn one() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&self, rhs: &Self) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mul(&self, rhs: &Self) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Polynomials with coefficient in `C`.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Polynomial<C: Semiring> {
|
||||||
|
coefficients: HashMap<u64, C>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Semiring> Semiring for Polynomial<C> {
|
||||||
|
fn zero() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn one() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&self, rhs: &Self) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mul(&self, rhs: &Self) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Semiring> From<C> for Polynomial<C> {
|
||||||
|
fn from(value: C) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Semiring> Polynomial<C> {
|
||||||
|
/// The variable X.
|
||||||
|
pub fn x() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluates the polynomial with the given value.
|
||||||
|
pub fn eval(&self, value: C) -> C {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FindIter<'s, T: Eq> {
|
||||||
|
query: &'s [T],
|
||||||
|
base: &'s [T],
|
||||||
|
curr: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Eq> Iterator for FindIter<'_, T> {
|
||||||
|
type Item = usize;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over substring query indexes in the base.
|
||||||
|
pub fn find<'s, T: Eq>(query: &'s [T], base: &'s [T]) -> impl 's + Iterator<Item = usize> {
|
||||||
|
FindIter {
|
||||||
|
query,
|
||||||
|
base,
|
||||||
|
curr: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
114
src/assignments/assignment06_grade.rs
Normal file
114
src/assignments/assignment06_grade.rs
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::super::assignment06::*;
|
||||||
|
|
||||||
|
fn test_polynomial<T: Semiring>() {
|
||||||
|
// x^2 + 5x + 6
|
||||||
|
let poly = Polynomial::add(
|
||||||
|
&Polynomial::add(
|
||||||
|
&Polynomial::mul(
|
||||||
|
&Polynomial::from(from_usize::<T>(1)),
|
||||||
|
&Polynomial::mul(&Polynomial::x(), &Polynomial::x()),
|
||||||
|
),
|
||||||
|
&Polynomial::mul(&Polynomial::from(from_usize::<T>(5)), &Polynomial::x()),
|
||||||
|
),
|
||||||
|
&Polynomial::from(from_usize::<T>(6)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 13^2 + 5*13 + 6
|
||||||
|
let value = poly.eval(from_usize(13));
|
||||||
|
|
||||||
|
assert_eq!(value, from_usize(13 * 13 + 5 * 13 + 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_polynomial_u64() {
|
||||||
|
test_polynomial::<u64>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_polynomial_f64() {
|
||||||
|
test_polynomial::<f64>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_polynomial_p_u64() {
|
||||||
|
test_polynomial::<Polynomial<u64>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_polynomial_xy() {
|
||||||
|
// (x+1)(y+2)
|
||||||
|
let poly: Polynomial<Polynomial<u64>> = Polynomial::mul(
|
||||||
|
&Polynomial::from(Polynomial::add(
|
||||||
|
&Polynomial::x(),
|
||||||
|
&Polynomial::from(from_usize::<u64>(1)),
|
||||||
|
)),
|
||||||
|
&(Polynomial::add(
|
||||||
|
&Polynomial::x(),
|
||||||
|
&Polynomial::from(Polynomial::from(from_usize::<u64>(2))),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// poly with y = x+3
|
||||||
|
let value = poly.eval(Polynomial::add(
|
||||||
|
&Polynomial::x(),
|
||||||
|
&Polynomial::from(from_usize::<u64>(3)),
|
||||||
|
));
|
||||||
|
|
||||||
|
// x^2 + 6x + 5
|
||||||
|
let expected = Polynomial::add(
|
||||||
|
&Polynomial::add(
|
||||||
|
&Polynomial::mul(
|
||||||
|
&Polynomial::from(from_usize::<u64>(1)),
|
||||||
|
&Polynomial::mul(&Polynomial::x(), &Polynomial::x()),
|
||||||
|
),
|
||||||
|
&Polynomial::mul(&Polynomial::from(from_usize::<u64>(6)), &Polynomial::x()),
|
||||||
|
),
|
||||||
|
&Polynomial::from(from_usize::<u64>(5)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(value, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_zero_remove() {
|
||||||
|
// (x-1)(x+1)
|
||||||
|
let poly: Polynomial<i64> = Polynomial::mul(
|
||||||
|
&Polynomial::add(&Polynomial::x(), &Polynomial::from(-1)),
|
||||||
|
&Polynomial::add(&Polynomial::x(), &Polynomial::from(1)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// (x-1)(x+1) == x^2 - 1
|
||||||
|
assert_eq!(
|
||||||
|
poly,
|
||||||
|
Polynomial::add(
|
||||||
|
&Polynomial::mul(&Polynomial::x(), &Polynomial::x()),
|
||||||
|
&Polynomial::from(-1)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_find() {
|
||||||
|
assert_eq!(
|
||||||
|
find("abc".as_bytes(), "abcdabcd".as_bytes()).collect::<Vec<usize>>(),
|
||||||
|
vec![0, 4]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find("aaba".as_bytes(), "aabaacaadaabaaba".as_bytes()).collect::<Vec<usize>>(),
|
||||||
|
vec![0, 9, 12]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find("ababac".as_bytes(), "abababcabababcabababc".as_bytes()).collect::<Vec<usize>>(),
|
||||||
|
vec![]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find("ababc".as_bytes(), "abc".as_bytes()).collect::<Vec<usize>>(),
|
||||||
|
vec![]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,3 +11,5 @@ pub mod assignment03;
|
|||||||
mod assignment03_grade;
|
mod assignment03_grade;
|
||||||
pub mod assignment04;
|
pub mod assignment04;
|
||||||
mod assignment04_grade;
|
mod assignment04_grade;
|
||||||
|
pub mod assignment06;
|
||||||
|
mod assignment06_grade;
|
||||||
|
|||||||
Reference in New Issue
Block a user