use {
std::{
ops,
cmp::Ordering,
iter::{
FromIterator,
FusedIterator,
},
},
metadata::Metadata,
extend_mut,
};
#[cfg(feature = "rayon")]
use rayon::prelude::*;
#[derive(Clone)]
pub struct PartitionVec<T> {
data: Vec<T>,
meta: Vec<Metadata>,
}
#[macro_export]
macro_rules! partition_vec {
($elem: expr; $len: expr) => {
$crate::PartitionVec::from_elem($elem, $len);
};
($($elem: expr),*) => {
{
let len = partitions_count_expr![$($elem),*];
let mut partition_vec = $crate::PartitionVec::with_capacity(len);
$(
partition_vec.push($elem);
)*
partition_vec
}
};
($($elem: expr,)*) => {
partition_vec![$($elem),*];
};
($($elem: expr => $set: expr),*) => {
{
let len = partitions_count_expr![$($elem),*];
let mut partition_vec = $crate::PartitionVec::with_capacity(len);
let mut map = ::std::collections::HashMap::new();
$(
let last_index = partition_vec.len();
partition_vec.push($elem);
if let Some(&index) = map.get(&$set) {
partition_vec.union(index, last_index);
} else {
map.insert($set, last_index);
}
)*
partition_vec
}
};
($($elem: expr => $set: expr,)*) => {
partition_vec![$($elem => $set),*];
}
}
impl<T> PartitionVec<T> {
#[inline]
pub fn new() -> Self {
Self {
data: Vec::new(),
meta: Vec::new(),
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self {
data: Vec::with_capacity(capacity),
meta: Vec::with_capacity(capacity),
}
}
pub fn union(&mut self, first_index: usize, second_index: usize) {
let i = self.find(first_index);
let j = self.find(second_index);
if i == j {
return
}
let link_i = self.meta[i].link();
let link_j = self.meta[j].link();
self.meta[i].set_link(link_j);
self.meta[j].set_link(link_i);
match Ord::cmp(&self.meta[i].rank(), &self.meta[j].rank()) {
Ordering::Less => {
self.meta[i].set_parent(j);
},
Ordering::Equal => {
self.meta[i].set_parent(j);
self.meta[j].set_rank(self.meta[j].rank() + 1);
},
Ordering::Greater => {
self.meta[j].set_parent(i);
},
}
}
#[inline]
pub fn same_set(&self, first_index: usize, second_index: usize) -> bool {
self.find(first_index) == self.find(second_index)
}
#[inline]
pub fn other_sets(&self, first_index: usize, second_index: usize) -> bool {
self.find(first_index) != self.find(second_index)
}
pub fn make_singleton(&mut self, index: usize) {
let mut current = self.meta[index].link();
if current != index {
let root = current;
self.meta[root].set_rank(1);
while self.meta[current].link() != index {
self.meta[current].set_parent(root);
current = self.meta[current].link();
}
self.meta[current].set_parent(root);
self.meta[current].set_link(root);
}
self.meta[index] = Metadata::new(index);
}
#[inline]
pub fn is_singleton(&self, index: usize) -> bool {
self.meta[index].link() == index
}
pub fn len_of_set(&self, index: usize) -> usize {
let mut current = self.meta[index].link();
let mut count = 1;
while current != index {
current = self.meta[current].link();
count += 1;
}
count
}
pub fn amount_of_sets(&self) -> usize {
let mut done = bit_vec![false; self.len()];
let mut count = 0;
for i in 0 .. self.len() {
if !done.get(self.find(i)).unwrap() {
done.set(self.find(i), true);
count += 1;
}
}
count
}
fn find(&self, index: usize) -> usize {
if self.meta[index].parent() == index {
index
} else {
let root = self.find(self.meta[index].parent());
self.meta[index].set_parent(root);
root
}
}
#[inline]
fn find_final(&self, mut index: usize) -> usize {
while index != self.meta[index].parent() {
index = self.meta[index].parent();
}
index
}
#[inline]
pub fn capacity(&self) -> usize {
usize::min(self.data.capacity(), self.meta.capacity())
}
#[inline]
pub fn push(&mut self, elem: T) {
let old_len = self.len();
self.data.push(elem);
self.meta.push(Metadata::new(old_len));
}
pub fn pop(&mut self) -> Option<T> {
let last_index = self.data.len() - 1;
self.make_singleton(last_index);
self.meta.pop()?;
Some(self.data.pop().unwrap())
}
pub fn insert(&mut self, index: usize, elem: T) {
for i in 0 .. self.meta.len() {
let parent = self.meta[i].parent();
if parent >= index {
self.meta[i].set_parent(parent + 1);
}
let link = self.meta[i].link();
if link >= index {
self.meta[i].set_link(link + 1);
}
}
self.data.insert(index, elem);
self.meta.insert(index, Metadata::new(index));
}
pub fn remove(&mut self, index: usize) -> T {
self.make_singleton(index);
self.meta.remove(index);
for i in 0 .. self.meta.len() {
let parent = self.meta[i].parent();
if parent > index {
self.meta[i].set_parent(parent - 1);
}
let link = self.meta[i].link();
if link > index {
self.meta[i].set_link(link - 1);
}
}
self.data.remove(index)
}
pub fn append(&mut self, other: &mut Self) {
let old_len = self.len();
self.data.append(&mut other.data);
self.meta.extend(other.meta.drain(..).map(|meta| {
let old = meta.parent();
meta.set_parent(old + old_len);
let old = meta.link();
meta.set_link(old + old_len);
meta
}));
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.data.reserve(additional);
self.meta.reserve(additional);
}
#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.data.reserve_exact(additional);
self.meta.reserve_exact(additional);
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.data.shrink_to_fit();
self.meta.shrink_to_fit();
}
pub fn truncate(&mut self, new_len: usize) {
if new_len >= self.len() {
return
}
for i in 0 .. new_len {
let parent = self.meta[i].parent();
let mut current = self.meta[i].link();
if parent >= new_len {
self.meta[i].set_parent(i);
self.meta[i].set_rank(1);
let mut previous = i;
let mut index_before_oob = if current >= new_len {
Some(previous)
} else {
None
};
while current != i {
if current >= new_len {
if index_before_oob.is_none() {
index_before_oob = Some(previous);
}
} else if let Some(index) = index_before_oob {
self.meta[index].set_link(current);
index_before_oob = None;
}
self.meta[current].set_parent(i);
previous = current;
current = self.meta[current].link();
}
if let Some(index) = index_before_oob {
self.meta[index].set_link(i);
}
} else if current >= new_len {
while current >= new_len {
current = self.meta[current].link();
}
self.meta[i].set_link(current);
}
}
self.data.truncate(new_len);
self.meta.truncate(new_len);
}
#[inline]
pub fn resize(&mut self, new_len: usize, value: T) where T: Clone {
let len = self.len();
match Ord::cmp(&new_len, &len) {
Ordering::Less => self.truncate(new_len),
Ordering::Equal => {},
Ordering::Greater => {
self.data.append(&mut vec![value; new_len - len]);
self.meta.extend((len .. new_len).map(Metadata::new));
}
}
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
self.meta.clear();
}
#[inline]
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[inline]
pub fn into_vec(self) -> Vec<T> {
self.data
}
#[inline]
pub fn into_boxed_slice(self) -> Box<[T]> {
self.data.into_boxed_slice()
}
#[inline]
pub fn as_slice(&self) -> & [T] {
self.data.as_slice()
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
self.data.as_mut_slice()
}
#[inline]
pub fn set(&self, index: usize) -> Set<T> {
let root = self.find_final(index);
self.meta[root].set_rank(1);
Set {
partition_vec: self,
current: Some(root),
root,
}
}
#[inline]
pub fn set_mut(&mut self, index: usize) -> SetMut<T> {
let root = self.find_final(index);
self.meta[root].set_rank(1);
SetMut {
partition_vec: self,
current: Some(root),
root,
}
}
#[inline]
pub fn all_sets(&self) -> AllSets<T> {
let len = self.len();
AllSets {
partition_vec: self,
done: bit_vec![false; len],
range: 0 .. len,
}
}
#[inline]
pub fn all_sets_mut(&mut self) -> AllSetsMut<T> {
let len = self.len();
AllSetsMut {
partition_vec: self,
done: bit_vec![false; len],
range: 0 .. len,
}
}
#[doc(hidden)]
#[inline]
pub fn from_elem(elem: T, len: usize) -> Self where T: Clone {
Self {
data: vec![elem; len],
meta: (0 .. len).map(Metadata::new).collect(),
}
}
}
impl<T> Default for PartitionVec<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> std::fmt::Debug for PartitionVec<T> where T: std::fmt::Debug {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
let mut map = std::collections::HashMap::with_capacity(self.len());
let mut builder = formatter.debug_list();
let mut names = 0;
for i in 0 .. self.len() {
let root = self.find(i);
let name = if let Some(&name) = map.get(&root) {
name
} else {
let new_name = names;
map.insert(root, new_name);
names += 1;
new_name
};
builder.entry(&format_args!("{:?} => {}", self.data[i], name));
}
builder.finish()
}
}
impl<T> PartialEq for PartitionVec<T> where T: PartialEq {
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false
}
let mut map = std::collections::HashMap::with_capacity(self.len());
for i in 0 .. self.len() {
if self.data[i] != other.data[i] {
return false
}
let self_root = self.find(i);
let other_root = other.find(i);
if let Some(&root) = map.get(&self_root) {
if root != other_root {
return false
}
} else {
map.insert(self_root, other_root);
}
}
true
}
}
impl<T> Eq for PartitionVec<T> where T: Eq {}
impl<T, I> ops::Index<I> for PartitionVec<T> where I: std::slice::SliceIndex<[T]> {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &I::Output {
(**self).index(index)
}
}
impl<T, I> ops::IndexMut<I> for PartitionVec<T> where I: std::slice::SliceIndex<[T]> {
#[inline]
fn index_mut(&mut self, index: I) -> &mut I::Output {
(**self).index_mut(index)
}
}
impl<T> ops::Deref for PartitionVec<T> {
type Target = [T];
fn deref(&self) -> &[T] {
&self.data
}
}
impl<T> ops::DerefMut for PartitionVec<T> {
fn deref_mut(&mut self) -> &mut [T] {
&mut self.data
}
}
impl<T> From<Vec<T>> for PartitionVec<T> {
fn from(vec: Vec<T>) -> Self {
let len = vec.len();
Self {
data: vec,
meta: (0 .. len).map(Metadata::new).collect(),
}
}
}
impl<T> FromIterator<T> for PartitionVec<T> {
fn from_iter<I>(iter: I) -> Self where I: IntoIterator<Item = T> {
let data = Vec::from_iter(iter);
let len = data.len();
Self {
data,
meta: (0 .. len).map(Metadata::new).collect(),
}
}
}
impl<'a, T> FromIterator<&'a T> for PartitionVec<T> where T: Copy + 'a {
fn from_iter<I>(iter: I) -> Self where I: IntoIterator<Item = &'a T> {
Self::from_iter(iter.into_iter().cloned())
}
}
#[cfg(feature = "rayon")]
impl<T> FromParallelIterator<T> for PartitionVec<T> where T: Send {
fn from_par_iter<I>(par_iter: I) -> Self where I: IntoParallelIterator<Item = T> {
let par_iter = par_iter.into_par_iter();
let mut partition = if let Some(len) = par_iter.opt_len() {
Self::with_capacity(len)
} else {
Self::new()
};
partition.par_extend(par_iter);
partition
}
}
#[cfg(feature = "rayon")]
impl<'a, T> FromParallelIterator<&'a T> for PartitionVec<T> where T: Copy+ Send + Sync + 'a {
fn from_par_iter<I>(par_iter: I) -> Self where I: IntoParallelIterator<Item = &'a T> {
Self::from_par_iter(par_iter.into_par_iter().cloned())
}
}
impl<T> IntoIterator for PartitionVec<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<T>;
fn into_iter(self) -> std::vec::IntoIter<T> {
self.data.into_iter()
}
}
impl<'a, T> IntoIterator for &'a PartitionVec<T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
fn into_iter(self) -> std::slice::Iter<'a, T> {
self.data.iter()
}
}
impl<'a, T> IntoIterator for &'a mut PartitionVec<T> {
type Item = &'a mut T;
type IntoIter = std::slice::IterMut<'a, T>;
fn into_iter(self) -> std::slice::IterMut<'a, T> {
self.data.iter_mut()
}
}
#[cfg(feature = "rayon")]
impl<T> IntoParallelIterator for PartitionVec<T> where T: Send {
type Item = T;
type Iter = rayon::vec::IntoIter<T>;
fn into_par_iter(self) -> Self::Iter {
self.data.into_par_iter()
}
}
#[cfg(feature = "rayon")]
impl<'a, T> IntoParallelIterator for &'a PartitionVec<T> where T: Send + Sync {
type Item = &'a T;
type Iter = rayon::slice::Iter<'a, T>;
fn into_par_iter(self) -> Self::Iter {
self.data.par_iter()
}
}
#[cfg(feature = "rayon")]
impl<'a, T> IntoParallelIterator for &'a mut PartitionVec<T> where T: Send + Sync {
type Item = &'a mut T;
type Iter = rayon::slice::IterMut<'a, T>;
fn into_par_iter(self) -> Self::Iter {
self.data.par_iter_mut()
}
}
impl<T> Extend<T> for PartitionVec<T> {
fn extend<I>(&mut self, iter: I) where I: IntoIterator<Item = T> {
let len = self.len();
self.data.extend(iter);
let new_len = self.data.len();
self.meta.extend((len .. new_len).map(Metadata::new));
}
}
impl<'a, T> Extend<&'a T> for PartitionVec<T> where T: Copy + 'a {
fn extend<I>(&mut self, iter: I) where I: IntoIterator<Item = &'a T> {
let len = self.len();
self.data.extend(iter);
let new_len = self.data.len();
self.meta.extend((len .. new_len).map(Metadata::new));
}
}
#[cfg(feature = "rayon")]
impl<T> ParallelExtend<T> for PartitionVec<T> where T: Send {
fn par_extend<I>(&mut self, par_iter: I) where I: IntoParallelIterator<Item = T>
{
let par_iter = par_iter.into_par_iter();
self.data.par_extend(par_iter);
self.meta.par_extend((0 .. self.data.len()).into_par_iter().map(Metadata::new));
}
}
#[cfg(feature = "rayon")]
impl<'a, T> ParallelExtend<&'a T> for PartitionVec<T> where T: Copy + Send + Sync + 'a {
fn par_extend<I>(&mut self, par_iter: I) where I: IntoParallelIterator<Item = &'a T> {
self.par_extend(par_iter.into_par_iter().cloned())
}
}
#[derive(Clone, Debug)]
pub struct Set<'a, T: 'a> {
partition_vec: &'a PartitionVec<T>,
current: Option<usize>,
root: usize,
}
impl<'a, T> Iterator for Set<'a, T> {
type Item = (usize, &'a T);
fn next(&mut self) -> Option<(usize, &'a T)> {
let current = self.current?;
self.partition_vec.meta[current].set_parent(self.root);
let next = self.partition_vec.meta[current].link();
self.current = if next == self.root {
None
} else {
Some(next)
};
Some((current, &self.partition_vec.data[current]))
}
}
impl<'a, T> FusedIterator for Set<'a, T> {}
#[derive(Debug)]
pub struct SetMut<'a, T: 'a> {
partition_vec: &'a mut PartitionVec<T>,
current: Option<usize>,
root: usize,
}
impl<'a, T> Iterator for SetMut<'a, T> {
type Item = (usize, &'a mut T);
fn next(&mut self) -> Option<(usize, &'a mut T)> {
let current = self.current?;
self.partition_vec.meta[current].set_parent(self.root);
let next = self.partition_vec.meta[current].link();
self.current = if next == self.root {
None
} else {
Some(next)
};
unsafe {
Some((current, extend_mut(&mut self.partition_vec.data[current])))
}
}
}
impl<'a, T> FusedIterator for SetMut<'a, T> {}
#[derive(Clone, Debug)]
pub struct AllSets<'a, T: 'a> {
partition_vec: &'a PartitionVec<T>,
done: bit_vec::BitVec,
range: ops::Range<usize>,
}
impl<'a, T> Iterator for AllSets<'a, T> {
type Item = Set<'a, T>;
fn next(&mut self) -> Option<Set<'a, T>> {
loop {
let index = self.range.next()?;
let root = self.partition_vec.find_final(index);
if !self.done.get(root).unwrap() {
self.done.set(root, true);
return Some(Set {
partition_vec: self.partition_vec,
current: Some(root),
root,
})
}
}
}
}
impl<'a, T> DoubleEndedIterator for AllSets<'a, T> {
fn next_back(&mut self) -> Option<Set<'a, T>> {
loop {
let index = self.range.next_back()?;
let root = self.partition_vec.find_final(index);
if !self.done.get(root).unwrap() {
self.done.set(root, true);
return Some(Set {
partition_vec: self.partition_vec,
current: Some(root),
root,
})
}
}
}
}
impl<'a, T> FusedIterator for AllSets<'a, T> {}
#[derive(Debug)]
pub struct AllSetsMut<'a, T: 'a> {
partition_vec: &'a mut PartitionVec<T>,
done: bit_vec::BitVec,
range: ops::Range<usize>,
}
impl<'a, T> Iterator for AllSetsMut<'a, T> {
type Item = SetMut<'a, T>;
fn next(&mut self) -> Option<SetMut<'a, T>> {
loop {
let index = self.range.next()?;
let root = self.partition_vec.find_final(index);
if !self.done.get(root).unwrap() {
self.done.set(root, true);
unsafe { return Some(SetMut {
partition_vec: extend_mut(self).partition_vec,
current: Some(root),
root,
})}
}
}
}
}
impl<'a, T> DoubleEndedIterator for AllSetsMut<'a, T> {
fn next_back(&mut self) -> Option<SetMut<'a, T>> {
loop {
let index = self.range.next_back()?;
let root = self.partition_vec.find_final(index);
if !self.done.get(root).unwrap() {
self.done.set(root, true);
unsafe { return Some(SetMut {
partition_vec: extend_mut(self).partition_vec,
current: Some(root),
root,
})}
}
}
}
}
impl<'a, T> FusedIterator for AllSetsMut<'a, T> {}