use std::{collections::BinaryHeap, cmp::Ordering};
pub struct SeqIter<T> {
ptr: usize,
iters: Vec<Box<dyn Iterator<Item = T>>>,
}
impl<T> SeqIter<T> {
pub fn new() -> SeqIter<T> {
return SeqIter { ptr: 0, iters: Vec::new() }
}
pub fn add(&mut self, iter: Box<dyn Iterator<Item=T>>) {
self.iters.push(iter);
}
fn get_current(&mut self) -> Option<&mut Box<dyn Iterator<Item = T>>> {
return self.iters.get_mut(self.ptr);
}
}
impl<T> Iterator for SeqIter<T> {
type Item = T;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
let target = self.get_current();
if target.is_none() {
return None
}
let next = target.unwrap().next();
if next.is_some() {
return next;
}
self.ptr += 1;
return self.next();
}
}
pub struct MultiIterator<T> {
head: Vec<T>,
iters: Vec<Box<dyn Iterator<Item = T>>>,
choose_function: fn(&Vec<T>)->Option<usize>
}
impl<T> MultiIterator<T> {
pub fn new(choose_function:fn(&Vec<T>)->Option<usize>) -> MultiIterator<T> {
MultiIterator {
head:vec!(),
iters: vec!(),
choose_function
}
}
pub fn add(&mut self, iter:Box<dyn Iterator<Item=T>>) {
let mut iter = iter;
let head = iter.next();
if head.is_some() {
self.head.push(head.unwrap());
self.iters.push(iter);
}
}
fn choose(&mut self)->Option<T> {
if self.head.len() == 0 {
return None;
}
let index = (self.choose_function)(&self.head);
if index.is_none() {
return None;
}
let index = index.unwrap();
if index > self.head.len() - 1 {
return None;
}
let iter = self.iters.get_mut(index);
let iter_next = iter.unwrap().next();
if iter_next.is_none() {
let _ = self.iters.remove(index);
let removed = self.head.remove(index);
return Some(removed);
} else {
let mut next_elem = iter_next.unwrap();
std::mem::swap(&mut self.head[index], &mut next_elem);
return Some(next_elem);
}
}
}
impl<T> Iterator for MultiIterator<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
return self.choose();
}
}
pub struct OrderedIterator<T>
where T:Ord
{
comparator: fn(&T, &T) -> Ordering,
head: BinaryHeap<HeapItem<T>>,
iters: Vec<Box<dyn Iterator<Item = T>>>,
}
struct HeapItem<T> {
what:T,
iter_index: usize,
comparator: fn(&T,&T)->std::cmp::Ordering
}
impl<T> Ord for HeapItem<T> {
fn cmp(&self, other:&Self) -> Ordering {
(self.comparator)(&self.what, &other.what)
}
}
impl<T> PartialEq for HeapItem<T> {
fn eq(&self, other: &Self) -> bool {
(self.comparator)(&self.what, &other.what) == Ordering::Equal
}
}
impl<T> Eq for HeapItem<T> {
}
impl<T> PartialOrd for HeapItem<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T> Iterator for OrderedIterator<T>
where T:Ord
{
type Item = T;
fn next(&mut self) -> Option<T> {
self.choose()
}
}
impl<T> OrderedIterator<T>
where T:Ord
{
pub fn new_min() -> OrderedIterator<T> {
let comparator = |x:&T, y:&T| {
y.cmp(&x)
};
OrderedIterator {
comparator,
head: BinaryHeap::new(),
iters: vec!(),
}
}
pub fn new_max() -> OrderedIterator<T> {
let comparator = |x:&T, y:&T| {
x.cmp(&y)
};
OrderedIterator {
comparator,
head: BinaryHeap::new(),
iters: vec!(),
}
}
pub fn add(&mut self, iter:Box<dyn Iterator<Item=T>>) {
let mut iter = iter;
let head = iter.next();
if head.is_some() {
let head = head.unwrap();
let item = HeapItem {
what: head,
comparator: self.comparator,
iter_index: self.iters.len(),
};
self.head.push(item);
self.iters.push(iter);
}
}
fn choose(&mut self)->Option<T> {
if self.head.len() == 0 {
return None;
}
let chosen = self.head.pop();
if chosen.is_none() {
return None;
}
let chosen = chosen.unwrap();
let chosen_index = chosen.iter_index;
let iter = self.iters.get_mut(chosen_index);
let iter_next = iter.unwrap().next();
if iter_next.is_some() {
let next_elem = iter_next.unwrap();
self.head.push(HeapItem {
comparator: self.comparator,
iter_index: chosen_index,
what: next_elem
});
}
return Some(chosen.what);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn seq_test() {
let v1 = vec![1,2,3,4,5];
let v2 = vec![6,7,8];
let v3 = vec![9,10];
let v4 = [1,2,4,5,6,7,8];
let mut seq_iter = SeqIter::new();
seq_iter.add(Box::new(v1.into_iter()));
seq_iter.add(Box::new(v2.into_iter()));
seq_iter.add(Box::new(v3.into_iter()));
seq_iter.add(Box::new(v4.into_iter()));
for i in seq_iter {
println!("{i}");
}
}
#[test]
fn test_multi_1() {
let v1: Vec<i32> = vec![1,2,3,4,5,11,19];
let v2: Vec<i32> = vec![1,7,8,12,44,231];
let v3: Vec<i32> = vec![3,5,7,9,10,1000];
let v4: [i32; 7] = [1,2,4,5,6,7,8];
let choose_fn = |x:&Vec<i32>| -> Option<usize> {
let result = x.iter().enumerate().min_by(|x, y| {
x.1.cmp(&y.1)
}).map(|x| x.0);
println!("Choosing from {:?} -> {:?}", x, result);
return result;
};
let mut min_iter = MultiIterator::new(choose_fn);
min_iter.add(Box::new(v1.into_iter()));
min_iter.add(Box::new(v2.into_iter()));
min_iter.add(Box::new(v3.into_iter()));
min_iter.add(Box::new(v4.into_iter()));
for i in min_iter{
println!("{i}");
}
}
#[test]
fn test_ordered() {
let v1 = vec![1,2,3,4,5,11,19];
let v2 = vec![1,7,8,12,44,231];
let v3 = vec![3,5,7,9,10,1000];
let v4 = [1,2,4,5,6,7,8];
let mut o_iter: OrderedIterator<_> = OrderedIterator::new_min();
o_iter.add(Box::new(v1.into_iter()));
o_iter.add(Box::new(v2.into_iter()));
o_iter.add(Box::new(v3.into_iter()));
o_iter.add(Box::new(v4.into_iter()));
for i in o_iter{
println!("{i}");
}
let v1 = vec!(9,4,2);
let v2:Vec<i32> = vec!();
let v3 = vec!(999,22,3,1);
let v4 = [992,222,211,20,19,2,1];
let mut o_iter = OrderedIterator::new_max();
o_iter.add(Box::new(v1.into_iter()));
o_iter.add(Box::new(v2.into_iter()));
o_iter.add(Box::new(v3.into_iter()));
o_iter.add(Box::new(v4.into_iter()));
for i in o_iter {
println!("{i}");
}
}
}