use crate::bools::random::{weighted_random_bools, WeightedRandomBools};
use crate::num::basic::traits::Zero;
use crate::random::Seed;
use crate::vecs::{random_values_from_vec, RandomValuesFromVec};
use itertools::Itertools;
use std::collections::{HashSet, VecDeque};
use std::fmt::Display;
use std::hash::Hash;
#[derive(Clone, Debug)]
pub struct NonzeroValues<I: Iterator>(I)
where
I::Item: PartialEq<I::Item> + Zero;
impl<I: Iterator> Iterator for NonzeroValues<I>
where
I::Item: PartialEq<I::Item> + Zero,
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
loop {
let x = self.0.next();
if x != Some(I::Item::ZERO) {
return x;
}
}
}
}
impl<I: DoubleEndedIterator> DoubleEndedIterator for NonzeroValues<I>
where
I::Item: PartialEq<I::Item> + Zero,
{
#[inline]
fn next_back(&mut self) -> Option<I::Item> {
loop {
let x = self.0.next_back();
if x != Some(I::Item::ZERO) {
return x;
}
}
}
}
#[inline]
pub const fn nonzero_values<I: Iterator>(xs: I) -> NonzeroValues<I>
where
I::Item: PartialEq<I::Item> + Zero,
{
NonzeroValues(xs)
}
pub fn is_constant<I: Iterator>(xs: I) -> bool
where
I::Item: Eq,
{
let mut first = None;
for x in xs {
if let Some(ref first) = first {
if x != *first {
return false;
}
} else {
first = Some(x);
}
}
true
}
#[inline]
pub fn count_is_at_least<I: Iterator>(xs: I, n: usize) -> bool {
xs.take(n).count() == n
}
#[inline]
pub fn count_is_at_most<I: Iterator>(xs: I, n: usize) -> bool {
xs.take(n + 1).count() <= n
}
#[inline]
pub fn is_unique<I: Iterator>(xs: I) -> bool
where
I::Item: Eq + Hash,
{
let mut set = HashSet::new();
for x in xs {
if !set.insert(x) {
return false;
}
}
true
}
pub fn first_and_last<I: Iterator>(xs: &mut I) -> Option<(I::Item, I::Item)>
where
I::Item: Clone,
{
xs.next().map(|first| {
if let Some(last) = xs.last() {
(first, last)
} else {
(first.clone(), first)
}
})
}
pub fn matching_intervals_in_iterator<I: Iterator, F: Fn(&I::Item) -> bool>(
xs: I,
predicate: F,
) -> Vec<(I::Item, I::Item)>
where
I::Item: Clone,
{
xs.group_by(predicate)
.into_iter()
.filter_map(|(b, mut group)| if b { first_and_last(&mut group) } else { None })
.collect()
}
#[derive(Clone, Debug)]
pub struct WithSpecialValue<I: Iterator>
where
I::Item: Clone,
{
bs: WeightedRandomBools,
special_value: I::Item,
xs: I,
}
impl<I: Iterator> Iterator for WithSpecialValue<I>
where
I::Item: Clone,
{
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
if self.bs.next().unwrap() {
Some(self.special_value.clone())
} else {
self.xs.next()
}
}
}
pub fn with_special_value<I: Iterator>(
seed: Seed,
special_value: I::Item,
p_numerator: u64,
p_denominator: u64,
xs_gen: &dyn Fn(Seed) -> I,
) -> WithSpecialValue<I>
where
I::Item: Clone,
{
WithSpecialValue {
bs: weighted_random_bools(seed.fork("bs"), p_numerator, p_denominator),
special_value,
xs: xs_gen(seed.fork("xs")),
}
}
#[derive(Clone, Debug)]
pub struct WithSpecialValues<I: Iterator>
where
I::Item: Clone,
{
bs: WeightedRandomBools,
special_values: RandomValuesFromVec<I::Item>,
xs: I,
}
impl<I: Iterator> Iterator for WithSpecialValues<I>
where
I::Item: Clone,
{
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
if self.bs.next().unwrap() {
self.special_values.next()
} else {
self.xs.next()
}
}
}
pub fn with_special_values<I: Iterator>(
seed: Seed,
special_values: Vec<I::Item>,
p_numerator: u64,
p_denominator: u64,
xs_gen: &dyn Fn(Seed) -> I,
) -> WithSpecialValues<I>
where
I::Item: Clone,
{
WithSpecialValues {
bs: weighted_random_bools(seed.fork("bs"), p_numerator, p_denominator),
special_values: random_values_from_vec(seed.fork("special_values"), special_values),
xs: xs_gen(seed.fork("xs")),
}
}
#[derive(Clone, Debug)]
pub struct IterWindows<I: Iterator>
where
I::Item: Clone,
{
xs: I,
window: VecDeque<I::Item>,
window_size: usize,
}
impl<I: Iterator> Iterator for IterWindows<I>
where
I::Item: Clone,
{
type Item = VecDeque<I::Item>;
fn next(&mut self) -> Option<VecDeque<I::Item>> {
if self.window.len() < self.window_size {
self.window = (&mut self.xs).take(self.window_size).collect();
if self.window.len() < self.window_size {
None
} else {
Some(self.window.clone())
}
} else {
let x = self.xs.next()?;
self.window.pop_front();
self.window.push_back(x);
Some(self.window.clone())
}
}
}
pub fn iter_windows<I: Iterator>(window_size: usize, xs: I) -> IterWindows<I>
where
I::Item: Clone,
{
assert_ne!(window_size, 0);
IterWindows {
xs,
window: VecDeque::with_capacity(window_size),
window_size,
}
}
pub fn prefix_to_string<I: Iterator>(mut xs: I, max_len: usize) -> String
where
I::Item: Display,
{
assert_ne!(max_len, 0);
let mut s = String::new();
s.push('[');
let mut first = true;
let mut done = false;
for _ in 0..max_len {
if let Some(x) = xs.next() {
if first {
first = false;
} else {
s.push_str(", ");
}
s.push_str(&x.to_string());
} else {
done = true;
break;
}
}
if !done && xs.next().is_some() {
s.push_str(", ...");
}
s.push(']');
s
}
pub mod bit_distributor;
pub mod comparison;
pub mod iterator_cache;