From 858ef49b59918687c9584c0d550087ed84ab118a Mon Sep 17 00:00:00 2001 From: static Date: Wed, 30 Oct 2024 04:43:50 +0000 Subject: [PATCH] Assignment 7 Done --- src/assignments/assignment07/generator.rs | 34 ++++++++- src/assignments/assignment07/my_itertools.rs | 65 ++++++++++++----- .../assignment07/small_exercises.rs | 72 +++++++++++++++---- src/assignments/assignment07/transform.rs | 19 +++-- 4 files changed, 150 insertions(+), 40 deletions(-) diff --git a/src/assignments/assignment07/generator.rs b/src/assignments/assignment07/generator.rs index e92f123..bb359bf 100644 --- a/src/assignments/assignment07/generator.rs +++ b/src/assignments/assignment07/generator.rs @@ -24,7 +24,10 @@ impl Iterator for Generator { type Item = T; fn next(&mut self) -> Option { - todo!() + match (self.f)(&mut self.state) { + Yielded::Value(v) => Some(v), + Yielded::Stop => None, + } } } @@ -32,12 +35,37 @@ impl Iterator for Generator { /// /// HINT: Consult pub fn fib_generator(first: usize, second: usize) -> Generator { - 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. /// /// HINT: Consult pub fn collatz_conjecture(start: usize) -> Generator { - 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) + }, + } } diff --git a/src/assignments/assignment07/my_itertools.rs b/src/assignments/assignment07/my_itertools.rs index 85dae05..7e2653b 100644 --- a/src/assignments/assignment07/my_itertools.rs +++ b/src/assignments/assignment07/my_itertools.rs @@ -6,8 +6,8 @@ use std::hash::Hash; /// Iterator that iterates over the given iterator and returns only unique elements. #[derive(Debug)] pub struct Unique { - // TODO: remove `_marker` and add necessary fields as you want - _marker: std::marker::PhantomData, + iterator: I, + used_values: HashSet, } impl Iterator for Unique @@ -17,15 +17,21 @@ where type Item = I::Item; fn next(&mut self) -> Option { - 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. #[derive(Debug)] pub struct Chain { - // TODO: remove `_marker` and add necessary fields as you want - _marker: std::marker::PhantomData<(I1, I2)>, + iterator1: I1, + iterator2: I2, } impl, I2: Iterator> Iterator @@ -34,22 +40,29 @@ impl, I2: Iterator> Itera type Item = T; fn next(&mut self) -> Option { - todo!() + if let Some(value) = self.iterator1.next() { + Some(value) + } else { + self.iterator2.next() + } } } /// Iterator that iterates over given iterator and enumerates each element. #[derive(Debug)] pub struct Enumerate { - // TODO: remove `_marker` and add necessary fields as you want - _marker: std::marker::PhantomData, + iterator: I, + index: usize, } impl Iterator for Enumerate { type Item = (usize, I::Item); fn next(&mut self) -> Option { - todo!() + let value = self.iterator.next()?; + let index = self.index; + self.index += 1; + Some((index, value)) } } @@ -59,15 +72,17 @@ impl Iterator for Enumerate { /// should be ignored. #[derive(Debug)] pub struct Zip { - // TODO: remove `_marker` and add necessary fields as you want - _marker: std::marker::PhantomData<(I1, I2)>, + iterator1: I1, + iterator2: I2, } impl Iterator for Zip { type Item = (I1::Item, I2::Item); fn next(&mut self) -> Option { - todo!() + let value1 = self.iterator1.next()?; + let value2 = self.iterator2.next()?; + Some((value1, value2)) } } @@ -78,7 +93,10 @@ pub trait MyIterTools: Iterator { where Self: Sized, { - todo!() + Unique { + iterator: self, + used_values: HashSet::new(), + } } /// Returns an iterator that chains `self` and `other` together. @@ -86,7 +104,10 @@ pub trait MyIterTools: Iterator { where Self: Sized, { - todo!() + Chain { + iterator1: self, + iterator2: other, + } } /// Returns an iterator that iterates over `self` and enumerates each element. @@ -94,7 +115,10 @@ pub trait MyIterTools: Iterator { where Self: Sized, { - todo!() + Enumerate { + iterator: self, + index: 0, + } } /// Returns an iterator that zips `self` and `other` together. @@ -102,7 +126,10 @@ pub trait MyIterTools: Iterator { where Self: Sized, { - todo!() + Zip { + iterator1: self, + iterator2: other, + } } /// Foldleft for `MyIterTools` @@ -111,7 +138,11 @@ pub trait MyIterTools: Iterator { Self: Sized, F: FnMut(Self::Item, T) -> T, { - todo!() + let mut result = init; + for value in self.by_ref() { + result = f(value, result); + } + result } } diff --git a/src/assignments/assignment07/small_exercises.rs b/src/assignments/assignment07/small_exercises.rs index 4555360..d697fff 100644 --- a/src/assignments/assignment07/small_exercises.rs +++ b/src/assignments/assignment07/small_exercises.rs @@ -10,7 +10,15 @@ impl Iterator for FindIter<'_, T> { type Item = usize; fn next(&mut self) -> Option { - 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 { - // TODO: remove `_marker` and add necessary fields as you want - _marker: std::marker::PhantomData, + first: T, + second: T, } impl + Copy> FibIter { fn new(first: T, second: T) -> Self { - todo!() + Self { first, second } } } @@ -42,7 +50,10 @@ where type Item = T; fn next(&mut self) -> Option { - todo!() + let value = self.first; + self.first = self.second; + self.second = self.second + value; + Some(value) } } @@ -53,8 +64,7 @@ pub fn fib(first: T, second: T) -> impl Iterator where T: std::ops::Add + Copy, { - todo!("replace `std::iter::empty() with your own implementation`"); - std::iter::empty() + FibIter::new(first, second) } /// Endpoint of range, inclusive or exclusive. @@ -68,12 +78,25 @@ pub enum Endpoint { } struct RangeIter { - // TODO: add necessary fields as you want + curr: isize, + step: isize, + last: isize, } impl RangeIter { 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; fn next(&mut self) -> Option { - 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. pub fn range(left: Endpoint, right: Endpoint, step: isize) -> impl Iterator { - todo!("replace `std::iter::empty() with your own implementation`"); - std::iter::empty() + RangeIter::new((left, right), step) } /// 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, } impl Iterator for Divisors { type Item = u64; fn next(&mut self) -> Option { - 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 { Divisors { n, - // TODO: you may define additional fields here + curr: 1, + vec: vec![], } } diff --git a/src/assignments/assignment07/transform.rs b/src/assignments/assignment07/transform.rs index e24588d..a383a68 100644 --- a/src/assignments/assignment07/transform.rs +++ b/src/assignments/assignment07/transform.rs @@ -10,7 +10,7 @@ pub trait Transform { impl, Tr2: Transform> Transform<(T1, T2)> for (Tr1, Tr2) { 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 Transform for Identity { fn transform(&self, value: T) -> T { - todo!() + value } } @@ -42,7 +42,7 @@ impl T> From for Custom { impl T> Transform for Custom { fn transform(&self, value: T) -> T { - todo!() + (self.f)(value) } } @@ -67,7 +67,10 @@ impl> Repeat { impl> Transform for Repeat { fn transform(&self, mut value: T) -> T { - todo!() + for _ in 0..self.n { + value = self.inner.transform(value) + } + value } } @@ -90,6 +93,12 @@ impl> RepeatUntilConverge { impl> Transform for RepeatUntilConverge { fn transform(&self, mut value: T) -> T { - todo!() + loop { + let old = value.clone(); + value = self.inner.transform(value); + if old == value { + return value; + } + } } }