use alloc::vec;
use alloc::vec::Vec;
const BITS: usize = 64;
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StateSet {
words: Vec<u64>,
}
impl StateSet {
pub fn new(capacity: usize) -> Self {
StateSet {
words: vec![0; capacity.div_ceil(BITS)],
}
}
pub fn capacity(&self) -> usize {
self.words.len() * BITS
}
pub fn insert(&mut self, i: usize) {
let w = i / BITS;
if w >= self.words.len() {
self.words.resize(w + 1, 0);
}
self.words[w] |= 1u64 << (i % BITS);
}
pub fn remove(&mut self, i: usize) {
let w = i / BITS;
if w < self.words.len() {
self.words[w] &= !(1u64 << (i % BITS));
}
}
pub fn contains(&self, i: usize) -> bool {
let w = i / BITS;
w < self.words.len() && (self.words[w] >> (i % BITS)) & 1 == 1
}
pub fn is_empty(&self) -> bool {
self.words.iter().all(|w| *w == 0)
}
pub fn len(&self) -> usize {
self.words.iter().map(|w| w.count_ones() as usize).sum()
}
pub fn clear(&mut self) {
for w in self.words.iter_mut() {
*w = 0;
}
}
pub fn union_with(&mut self, other: &StateSet) {
if other.words.len() > self.words.len() {
self.words.resize(other.words.len(), 0);
}
for (a, b) in self.words.iter_mut().zip(other.words.iter()) {
*a |= *b;
}
}
pub fn difference_with(&mut self, other: &StateSet) {
for (a, b) in self.words.iter_mut().zip(other.words.iter()) {
*a &= !*b;
}
}
pub fn intersects(&self, other: &StateSet) -> bool {
self.words
.iter()
.zip(other.words.iter())
.any(|(a, b)| a & b != 0)
}
pub fn any_in_range(&self, lo: usize, hi: usize) -> bool {
let mut i = lo;
while i <= hi {
if self.contains(i) {
return true;
}
i += 1;
}
false
}
pub fn to_vec(&self) -> Vec<usize> {
let mut out = Vec::new();
for (wi, w) in self.words.iter().enumerate() {
let mut bits = *w;
while bits != 0 {
let b = bits.trailing_zeros() as usize;
out.push(wi * BITS + b);
bits &= bits - 1;
}
}
out
}
pub fn to_vec_rev(&self) -> Vec<usize> {
let mut v = self.to_vec();
v.reverse();
v
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn insert_remove_iterate() {
let mut s = StateSet::new(130);
s.insert(0);
s.insert(64);
s.insert(129);
assert!(s.contains(64));
assert_eq!(s.to_vec(), vec![0, 64, 129]);
assert_eq!(s.to_vec_rev(), vec![129, 64, 0]);
s.remove(64);
assert_eq!(s.len(), 2);
assert!(s.any_in_range(100, 129));
assert!(!s.any_in_range(1, 128));
let mut t = StateSet::new(130);
t.insert(129);
assert!(s.intersects(&t));
s.difference_with(&t);
assert_eq!(s.to_vec(), vec![0]);
s.insert(300);
assert!(s.contains(300));
s.clear();
assert!(s.is_empty());
}
}