mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-15 22:48:45 +00:00
Assignment 7 Done
This commit is contained in:
@@ -24,7 +24,10 @@ impl<T, S> Iterator for Generator<T, S> {
|
|||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
match (self.f)(&mut self.state) {
|
||||||
|
Yielded::Value(v) => Some(v),
|
||||||
|
Yielded::Stop => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,12 +35,37 @@ impl<T, S> Iterator for Generator<T, S> {
|
|||||||
///
|
///
|
||||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Fibonacci_sequence>
|
/// HINT: Consult <https://en.wikipedia.org/wiki/Fibonacci_sequence>
|
||||||
pub fn fib_generator(first: usize, second: usize) -> Generator<usize, (usize, usize)> {
|
pub fn fib_generator(first: usize, second: usize) -> Generator<usize, (usize, usize)> {
|
||||||
todo!()
|
Generator {
|
||||||
|
state: (first, second),
|
||||||
|
f: |(a, b)| {
|
||||||
|
let value = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b += value;
|
||||||
|
Yielded::Value(value)
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a generator that yields collatz numbers.
|
/// Returns a generator that yields collatz numbers.
|
||||||
///
|
///
|
||||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Collatz_conjecture>
|
/// HINT: Consult <https://en.wikipedia.org/wiki/Collatz_conjecture>
|
||||||
pub fn collatz_conjecture(start: usize) -> Generator<usize, usize> {
|
pub fn collatz_conjecture(start: usize) -> Generator<usize, usize> {
|
||||||
todo!()
|
Generator {
|
||||||
|
state: start,
|
||||||
|
f: |start| {
|
||||||
|
let value = *start;
|
||||||
|
if value == 0 {
|
||||||
|
return Yielded::Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
*start = if value == 1 {
|
||||||
|
0
|
||||||
|
} else if value % 2 == 0 {
|
||||||
|
value / 2
|
||||||
|
} else {
|
||||||
|
3 * value + 1
|
||||||
|
};
|
||||||
|
Yielded::Value(value)
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use std::hash::Hash;
|
|||||||
/// Iterator that iterates over the given iterator and returns only unique elements.
|
/// Iterator that iterates over the given iterator and returns only unique elements.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Unique<I: Iterator> {
|
pub struct Unique<I: Iterator> {
|
||||||
// TODO: remove `_marker` and add necessary fields as you want
|
iterator: I,
|
||||||
_marker: std::marker::PhantomData<I>,
|
used_values: HashSet<I::Item>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Iterator> Iterator for Unique<I>
|
impl<I: Iterator> Iterator for Unique<I>
|
||||||
@@ -17,15 +17,21 @@ where
|
|||||||
type Item = I::Item;
|
type Item = I::Item;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
for value in self.iterator.by_ref() {
|
||||||
|
if !self.used_values.contains(&value) {
|
||||||
|
let _ = self.used_values.insert(value.clone());
|
||||||
|
return Some(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator that chains two iterators together.
|
/// Iterator that chains two iterators together.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Chain<I1: Iterator, I2: Iterator> {
|
pub struct Chain<I1: Iterator, I2: Iterator> {
|
||||||
// TODO: remove `_marker` and add necessary fields as you want
|
iterator1: I1,
|
||||||
_marker: std::marker::PhantomData<(I1, I2)>,
|
iterator2: I2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Eq + Hash + Clone, I1: Iterator<Item = T>, I2: Iterator<Item = T>> Iterator
|
impl<T: Eq + Hash + Clone, I1: Iterator<Item = T>, I2: Iterator<Item = T>> Iterator
|
||||||
@@ -34,22 +40,29 @@ impl<T: Eq + Hash + Clone, I1: Iterator<Item = T>, I2: Iterator<Item = T>> Itera
|
|||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
if let Some(value) = self.iterator1.next() {
|
||||||
|
Some(value)
|
||||||
|
} else {
|
||||||
|
self.iterator2.next()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator that iterates over given iterator and enumerates each element.
|
/// Iterator that iterates over given iterator and enumerates each element.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Enumerate<I: Iterator> {
|
pub struct Enumerate<I: Iterator> {
|
||||||
// TODO: remove `_marker` and add necessary fields as you want
|
iterator: I,
|
||||||
_marker: std::marker::PhantomData<I>,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Iterator> Iterator for Enumerate<I> {
|
impl<I: Iterator> Iterator for Enumerate<I> {
|
||||||
type Item = (usize, I::Item);
|
type Item = (usize, I::Item);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
let value = self.iterator.next()?;
|
||||||
|
let index = self.index;
|
||||||
|
self.index += 1;
|
||||||
|
Some((index, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,15 +72,17 @@ impl<I: Iterator> Iterator for Enumerate<I> {
|
|||||||
/// should be ignored.
|
/// should be ignored.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Zip<I1: Iterator, I2: Iterator> {
|
pub struct Zip<I1: Iterator, I2: Iterator> {
|
||||||
// TODO: remove `_marker` and add necessary fields as you want
|
iterator1: I1,
|
||||||
_marker: std::marker::PhantomData<(I1, I2)>,
|
iterator2: I2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I1: Iterator, I2: Iterator> Iterator for Zip<I1, I2> {
|
impl<I1: Iterator, I2: Iterator> Iterator for Zip<I1, I2> {
|
||||||
type Item = (I1::Item, I2::Item);
|
type Item = (I1::Item, I2::Item);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
let value1 = self.iterator1.next()?;
|
||||||
|
let value2 = self.iterator2.next()?;
|
||||||
|
Some((value1, value2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +93,10 @@ pub trait MyIterTools: Iterator {
|
|||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
todo!()
|
Unique {
|
||||||
|
iterator: self,
|
||||||
|
used_values: HashSet::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that chains `self` and `other` together.
|
/// Returns an iterator that chains `self` and `other` together.
|
||||||
@@ -86,7 +104,10 @@ pub trait MyIterTools: Iterator {
|
|||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
todo!()
|
Chain {
|
||||||
|
iterator1: self,
|
||||||
|
iterator2: other,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that iterates over `self` and enumerates each element.
|
/// Returns an iterator that iterates over `self` and enumerates each element.
|
||||||
@@ -94,7 +115,10 @@ pub trait MyIterTools: Iterator {
|
|||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
todo!()
|
Enumerate {
|
||||||
|
iterator: self,
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that zips `self` and `other` together.
|
/// Returns an iterator that zips `self` and `other` together.
|
||||||
@@ -102,7 +126,10 @@ pub trait MyIterTools: Iterator {
|
|||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
todo!()
|
Zip {
|
||||||
|
iterator1: self,
|
||||||
|
iterator2: other,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Foldleft for `MyIterTools`
|
/// Foldleft for `MyIterTools`
|
||||||
@@ -111,7 +138,11 @@ pub trait MyIterTools: Iterator {
|
|||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnMut(Self::Item, T) -> T,
|
F: FnMut(Self::Item, T) -> T,
|
||||||
{
|
{
|
||||||
todo!()
|
let mut result = init;
|
||||||
|
for value in self.by_ref() {
|
||||||
|
result = f(value, result);
|
||||||
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,15 @@ impl<T: Eq> Iterator for FindIter<'_, T> {
|
|||||||
type Item = usize;
|
type Item = usize;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
while self.curr + self.query.len() <= self.base.len() {
|
||||||
|
let curr = self.curr;
|
||||||
|
self.curr += 1;
|
||||||
|
|
||||||
|
if &self.base[curr..(curr + self.query.len())] == self.query {
|
||||||
|
return Some(curr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,13 +33,13 @@ pub fn find<'s, T: Eq>(query: &'s [T], base: &'s [T]) -> impl 's + Iterator<Item
|
|||||||
|
|
||||||
/// Implement generic fibonacci iterator
|
/// Implement generic fibonacci iterator
|
||||||
struct FibIter<T> {
|
struct FibIter<T> {
|
||||||
// TODO: remove `_marker` and add necessary fields as you want
|
first: T,
|
||||||
_marker: std::marker::PhantomData<T>,
|
second: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: std::ops::Add<Output = T> + Copy> FibIter<T> {
|
impl<T: std::ops::Add<Output = T> + Copy> FibIter<T> {
|
||||||
fn new(first: T, second: T) -> Self {
|
fn new(first: T, second: T) -> Self {
|
||||||
todo!()
|
Self { first, second }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +50,10 @@ where
|
|||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
let value = self.first;
|
||||||
|
self.first = self.second;
|
||||||
|
self.second = self.second + value;
|
||||||
|
Some(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,8 +64,7 @@ pub fn fib<T>(first: T, second: T) -> impl Iterator<Item = T>
|
|||||||
where
|
where
|
||||||
T: std::ops::Add<Output = T> + Copy,
|
T: std::ops::Add<Output = T> + Copy,
|
||||||
{
|
{
|
||||||
todo!("replace `std::iter::empty() with your own implementation`");
|
FibIter::new(first, second)
|
||||||
std::iter::empty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Endpoint of range, inclusive or exclusive.
|
/// Endpoint of range, inclusive or exclusive.
|
||||||
@@ -68,12 +78,25 @@ pub enum Endpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct RangeIter {
|
struct RangeIter {
|
||||||
// TODO: add necessary fields as you want
|
curr: isize,
|
||||||
|
step: isize,
|
||||||
|
last: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RangeIter {
|
impl RangeIter {
|
||||||
fn new(endpoints: (Endpoint, Endpoint), step: isize) -> Self {
|
fn new(endpoints: (Endpoint, Endpoint), step: isize) -> Self {
|
||||||
todo!()
|
let c = if step > 0 { 1 } else { -1 };
|
||||||
|
Self {
|
||||||
|
curr: match endpoints.0 {
|
||||||
|
Endpoint::Inclusive(v) => v,
|
||||||
|
Endpoint::Exclusive(v) => v + c,
|
||||||
|
},
|
||||||
|
step,
|
||||||
|
last: match endpoints.1 {
|
||||||
|
Endpoint::Inclusive(v) => v,
|
||||||
|
Endpoint::Exclusive(v) => v - c,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,14 +104,19 @@ impl Iterator for RangeIter {
|
|||||||
type Item = isize;
|
type Item = isize;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
if self.step > 0 && self.curr > self.last || self.step < 0 && self.curr < self.last {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let value = self.curr;
|
||||||
|
self.curr += self.step;
|
||||||
|
Some(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the range [left, right) with the given step.
|
/// Returns an iterator over the range [left, right) with the given step.
|
||||||
pub fn range(left: Endpoint, right: Endpoint, step: isize) -> impl Iterator<Item = isize> {
|
pub fn range(left: Endpoint, right: Endpoint, step: isize) -> impl Iterator<Item = isize> {
|
||||||
todo!("replace `std::iter::empty() with your own implementation`");
|
RangeIter::new((left, right), step)
|
||||||
std::iter::empty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write an iterator that returns all divisors of n in increasing order.
|
/// Write an iterator that returns all divisors of n in increasing order.
|
||||||
@@ -100,14 +128,27 @@ pub fn range(left: Endpoint, right: Endpoint, step: isize) -> impl Iterator<Item
|
|||||||
/// then n/x is a divisor of n that is smaller than sqrt(n).
|
/// then n/x is a divisor of n that is smaller than sqrt(n).
|
||||||
struct Divisors {
|
struct Divisors {
|
||||||
n: u64,
|
n: u64,
|
||||||
// TODO: you may define additional fields here
|
curr: u64,
|
||||||
|
vec: Vec<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for Divisors {
|
impl Iterator for Divisors {
|
||||||
type Item = u64;
|
type Item = u64;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
todo!()
|
while self.curr * self.curr <= self.n {
|
||||||
|
let curr = self.curr;
|
||||||
|
self.curr += 1;
|
||||||
|
|
||||||
|
if self.n % curr == 0 {
|
||||||
|
if curr * curr != self.n {
|
||||||
|
self.vec.push(self.n / curr);
|
||||||
|
}
|
||||||
|
return Some(curr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.vec.pop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +156,7 @@ impl Iterator for Divisors {
|
|||||||
pub fn divisors(n: u64) -> impl Iterator<Item = u64> {
|
pub fn divisors(n: u64) -> impl Iterator<Item = u64> {
|
||||||
Divisors {
|
Divisors {
|
||||||
n,
|
n,
|
||||||
// TODO: you may define additional fields here
|
curr: 1,
|
||||||
|
vec: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pub trait Transform<T> {
|
|||||||
|
|
||||||
impl<T1, T2, Tr1: Transform<T1>, Tr2: Transform<T2>> Transform<(T1, T2)> for (Tr1, Tr2) {
|
impl<T1, T2, Tr1: Transform<T1>, Tr2: Transform<T2>> Transform<(T1, T2)> for (Tr1, Tr2) {
|
||||||
fn transform(&self, value: (T1, T2)) -> (T1, T2) {
|
fn transform(&self, value: (T1, T2)) -> (T1, T2) {
|
||||||
todo!()
|
(self.0.transform(value.0), self.1.transform(value.1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ pub struct Identity;
|
|||||||
|
|
||||||
impl<T> Transform<T> for Identity {
|
impl<T> Transform<T> for Identity {
|
||||||
fn transform(&self, value: T) -> T {
|
fn transform(&self, value: T) -> T {
|
||||||
todo!()
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ impl<T, F: Fn(T) -> T> From<F> for Custom<T, F> {
|
|||||||
|
|
||||||
impl<T, F: Fn(T) -> T> Transform<T> for Custom<T, F> {
|
impl<T, F: Fn(T) -> T> Transform<T> for Custom<T, F> {
|
||||||
fn transform(&self, value: T) -> T {
|
fn transform(&self, value: T) -> T {
|
||||||
todo!()
|
(self.f)(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,10 @@ impl<T, Tr: Transform<T>> Repeat<T, Tr> {
|
|||||||
|
|
||||||
impl<T, Tr: Transform<T>> Transform<T> for Repeat<T, Tr> {
|
impl<T, Tr: Transform<T>> Transform<T> for Repeat<T, Tr> {
|
||||||
fn transform(&self, mut value: T) -> T {
|
fn transform(&self, mut value: T) -> T {
|
||||||
todo!()
|
for _ in 0..self.n {
|
||||||
|
value = self.inner.transform(value)
|
||||||
|
}
|
||||||
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +93,12 @@ impl<T: Clone + Eq, Tr: Transform<T>> RepeatUntilConverge<T, Tr> {
|
|||||||
|
|
||||||
impl<T: Clone + Eq, Tr: Transform<T>> Transform<T> for RepeatUntilConverge<T, Tr> {
|
impl<T: Clone + Eq, Tr: Transform<T>> Transform<T> for RepeatUntilConverge<T, Tr> {
|
||||||
fn transform(&self, mut value: T) -> T {
|
fn transform(&self, mut value: T) -> T {
|
||||||
todo!()
|
loop {
|
||||||
|
let old = value.clone();
|
||||||
|
value = self.inner.transform(value);
|
||||||
|
if old == value {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user