use std::fmt::*;
use std::hash::{Hash, Hasher};
use std::iter::{once, repeat, FromIterator};
use std::ops::{BitAndAssign, BitOrAssign};
#[derive(Clone)]
pub enum BitSet {
Small(u64),
Large(Vec<u64>),
}
#[allow(unused)]
impl BitSet {
pub fn new() -> Self {
BitSet::Small(0)
}
fn grow(&mut self, bit_size: usize) {
*self = match std::mem::replace(self, BitSet::Small(0)) {
BitSet::Small(bits) => {
if bit_size > 63 {
BitSet::Large(
std::iter::once(bits)
.chain(std::iter::repeat(0))
.take(1 + bit_size / 64)
.collect(),
)
} else {
BitSet::Small(bits)
}
}
BitSet::Large(mut vec) => {
while vec.len() < 1 + bit_size / 64 {
vec.push(0);
}
BitSet::Large(vec)
}
};
}
fn shrink(&mut self) {
if let BitSet::Large(ref mut vec) = self {
while let Some(&0) = vec.last() {
vec.pop();
}
}
}
pub fn insert(&mut self, bit: usize) {
self.grow(bit);
match self {
BitSet::Small(ref mut bits) => {
bits.bitor_assign(1u64 << bit);
}
BitSet::Large(ref mut vec) => {
let block = bit / 64;
vec[block].bitor_assign(1u64 << (bit & 0x3f));
}
}
}
pub fn remove(&mut self, bit: usize) {
match self {
BitSet::Small(ref mut bits) => {
bits.bitand_assign(!(1u64 << (bit & 0x03f)));
}
BitSet::Large(ref mut vec) => {
let block = bit / 64;
if vec.len() > block {
vec[block].bitand_assign(!(1u64 << (bit & 0x3f)));
}
}
}
self.shrink();
}
pub fn contains(&self, bit: usize) -> bool {
match self {
BitSet::Small(bits) => {
if bit < 64 {
*bits & (1u64 << bit) > 0
} else {
false
}
}
BitSet::Large(vec) => {
let block = bit / 64;
if block < vec.len() {
vec[block] & (1u64 << (bit & 0x3f)) > 0
} else {
false
}
}
}
}
pub fn iter(&self) -> BitIter {
match self {
BitSet::Small(bits) => BitIter {
current: *bits,
offset: 0,
remaining: &[],
},
BitSet::Large(blocks) => {
let slice = blocks.as_slice();
let (¤t, remaining) = slice.split_first().unwrap_or((&0, &[]));
BitIter {
current,
remaining,
offset: 0,
}
}
}
}
pub fn is_empty(&self) -> bool {
match self {
BitSet::Small(bits) => *bits == 0,
BitSet::Large(vec) => vec.last().map(|&last| last == 0).unwrap_or(true),
}
}
pub fn apply<F: Fn(u64, u64) -> u64>(&self, other: &Self, f: F) -> Self {
let mut result = match (self, other) {
(&BitSet::Small(bits), &BitSet::Small(other_bits)) => BitSet::Small(f(bits, other_bits)),
(&BitSet::Small(bits), &BitSet::Large(ref vec)) | (&BitSet::Large(ref vec), &BitSet::Small(bits)) => {
BitSet::Large(
vec.iter()
.cloned()
.zip(once(bits).chain(repeat(0)))
.map(|(a, b)| f(a, b))
.collect(),
)
}
(&BitSet::Large(ref vec), &BitSet::Large(ref other_vec)) => {
if vec.len() > other_vec.len() {
BitSet::Large(
vec.iter()
.cloned()
.zip(other_vec.iter().cloned().chain(repeat(0)))
.map(|(a, b)| f(a, b))
.collect(),
)
} else {
BitSet::Large(
other_vec
.iter()
.cloned()
.zip(vec.iter().cloned().chain(repeat(0)))
.map(|(a, b)| f(a, b))
.collect(),
)
}
}
};
result.shrink();
result
}
pub fn difference(&self, other: &Self) -> Self {
self.apply(other, |a, b| a ^ b)
}
pub fn union(&self, other: &Self) -> Self {
self.apply(other, |a, b| a | b)
}
pub fn intersection(&self, other: &Self) -> Self {
match (self, other) {
(&BitSet::Small(bits), &BitSet::Small(other_bits)) => BitSet::Small(bits & other_bits),
(&BitSet::Small(bits), &BitSet::Large(ref vec)) | (&BitSet::Large(ref vec), &BitSet::Small(bits)) => {
match vec.len() {
0 => BitSet::Small(0),
_ => BitSet::Small(bits & vec[0]),
}
}
(&BitSet::Large(ref vec), &BitSet::Large(ref other_vec)) => {
let mut result = BitSet::Large(vec.iter().zip(other_vec.iter()).map(|(&a, &b)| a & b).collect());
result.shrink();
result
}
}
}
}
impl Default for BitSet {
fn default() -> Self {
Self::new()
}
}
pub struct BitIter<'a> {
remaining: &'a [u64],
offset: usize,
current: u64,
}
impl<'a> Iterator for BitIter<'a> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
while self.current == 0 {
self.current = self.remaining.get(0).cloned()?;
self.offset += 64;
self.remaining = &self.remaining[1..];
}
let bit = self.current & !(self.current - 1);
self.current = self.current & (self.current - 1);
let mut c = 64;
if bit > 0 {
c -= 1
};
if bit & 0x00000000ffffffff > 0 {
c -= 32
};
if bit & 0x0000ffff0000ffff > 0 {
c -= 16
};
if bit & 0x00ff00ff00ff00ff > 0 {
c -= 8
};
if bit & 0x0f0f0f0f0f0f0f0f > 0 {
c -= 4
};
if bit & 0x3333333333333333 > 0 {
c -= 2
};
if bit & 0x5555555555555555 > 0 {
c -= 1
};
Some(self.offset + c)
}
}
impl FromIterator<usize> for BitSet {
fn from_iter<T: IntoIterator<Item = usize>>(iter: T) -> Self {
let mut result = BitSet::new();
for item in iter.into_iter() {
result.insert(item);
}
result
}
}
impl Hash for BitSet {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
BitSet::Small(bits) => bits.hash(state),
BitSet::Large(ref vec) => {
for block in vec.iter() {
block.hash(state);
}
}
}
}
}
impl PartialEq for BitSet {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(&BitSet::Small(bits), &BitSet::Small(other_bits)) => bits == other_bits,
(&BitSet::Small(bits), &BitSet::Large(ref vec)) | (&BitSet::Large(ref vec), &BitSet::Small(bits)) => {
match vec.len() {
0 => bits == 0,
1 => bits == vec[0],
_ => false,
}
}
(&BitSet::Large(ref vec), &BitSet::Large(ref other_vec)) => vec.iter().eq(other_vec.iter()),
}
}
}
impl Eq for BitSet {}
impl Debug for BitSet {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
f.debug_list().entries(self.iter()).finish()
}
}