//! Implement functions using `Iterator` trait struct FindIter<'s, T: Eq> { query: &'s [T], base: &'s [T], curr: usize, } impl Iterator for FindIter<'_, T> { type Item = usize; fn next(&mut self) -> Option { 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 } } /// 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 { FindIter { query, base, curr: 0, } } /// Implement generic fibonacci iterator struct FibIter { first: T, second: T, } impl + Copy> FibIter { fn new(first: T, second: T) -> Self { Self { first, second } } } impl Iterator for FibIter where T: std::ops::Add + Copy, { type Item = T; fn next(&mut self) -> Option { let value = self.first; self.first = self.second; self.second = self.second + value; Some(value) } } /// Returns and iterator over the generic fibonacci sequence starting from `first` and `second`. /// This is a generic version of `fibonacci` function, which works for any types that implements /// `std::ops::Add` trait. pub fn fib(first: T, second: T) -> impl Iterator where T: std::ops::Add + Copy, { FibIter::new(first, second) } /// Endpoint of range, inclusive or exclusive. #[derive(Debug)] pub enum Endpoint { /// Inclusive endpoint Inclusive(isize), /// Exclusive endpoint Exclusive(isize), } struct RangeIter { curr: isize, step: isize, last: isize, } impl RangeIter { fn new(endpoints: (Endpoint, Endpoint), step: isize) -> Self { 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, }, } } } impl Iterator for RangeIter { type Item = isize; fn next(&mut self) -> Option { 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 { RangeIter::new((left, right), step) } /// Write an iterator that returns all divisors of n in increasing order. /// Assume n > 0. /// /// Hint: trying all candidates from 1 to n will most likely time out! /// To optimize it, make use of the following fact: /// if x is a divisor of n that is greater than sqrt(n), /// then n/x is a divisor of n that is smaller than sqrt(n). struct Divisors { n: u64, curr: u64, vec: Vec, } impl Iterator for Divisors { type Item = u64; fn next(&mut self) -> Option { 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() } } /// Returns an iterator over the divisors of n. pub fn divisors(n: u64) -> impl Iterator { Divisors { n, curr: 1, vec: vec![], } }