use crate::bitset::BitSet;
use crate::u64impl::DenseBitSet;
use std::cmp::{max, min};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::{
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, ShlAssign, Shr,
ShrAssign,
};
#[derive(Default, Clone)]
pub struct DenseBitSetExtended {
state: Vec<u64>,
size: usize,
}
impl DenseBitSetExtended {
pub fn new() -> Self {
Self {
state: vec![],
size: 0,
}
}
pub fn with_capacity(size: usize) -> Self {
assert!(
size < 64_000,
"(Temporary?) We don't allow bitsets larger than 64k for now."
);
let state: Vec<u64> = Vec::with_capacity(1 + (size >> 6));
Self { state, size: 0 }
}
pub fn from_dense_bitset(dbs: DenseBitSet) -> Self {
let state = vec![dbs.to_integer()];
let size = 64;
Self { state, size }
}
pub fn all(&self) -> bool {
let l = self.state.len();
for i in 0..l - 1 {
if self.state[i] != u64::max_value() {
return false;
}
}
if self.size % 64 == 0 {
if self.state[l - 1] != u64::max_value() {
return false;
}
} else if self.state[l - 1] != ((1 << (self.size % 64)) - 1) {
return false;
}
true
}
pub fn any(&self) -> bool {
for &s in &self.state {
if s > 0 {
return true;
}
}
false
}
pub fn none(&self) -> bool {
!self.any()
}
pub fn get_size(&self) -> usize {
self.size
}
pub fn extract_u64(&self, position: usize, length: usize) -> u64 {
assert!(
length <= 64,
"This implementation is currently limited to 64 bit bitsets."
);
assert!(length > 0, "Cannot extract a zero-width slice.");
if position >= self.size {
return 0;
}
let idx = position >> 6;
let offset = position % 64;
let actual_length = if position + length > self.size {
self.size - position
} else {
length
};
if actual_length + offset < 64 {
(self.get(idx) >> offset) & ((1 << actual_length) - 1)
} else if actual_length + offset == 64 {
self.get(idx) >> offset
} else {
let remainder = actual_length + offset - 64;
let lsb = self.state[idx] >> offset;
if self.state.len() == idx + 1 {
lsb
} else {
let msb = self.state[idx + 1] & ((1 << remainder) - 1);
(msb << (64 - offset)) | lsb
}
}
}
pub fn subset(&self, position: usize, length: usize) -> Self {
if length == 0 {
return Self {
state: vec![],
size: 0,
};
}
let segments = 1 + ((length - 1) >> 6);
let mut state = vec![];
for l in 0..segments {
state.push(self.extract_u64(l * 64 + position, 64));
}
Self {
state,
size: length,
}
}
pub fn insert(&mut self, other: &Self, position: usize, length: usize) {
let l = (length >> 6) + 1;
let size_before_insertion = self.size;
if length % 64 == 0 {
for i in 0..l {
self.insert_u64(other.state[i], position + i * 64, 64);
}
} else {
for i in 0..l - 1 {
self.insert_u64(other.state[i], position + i * 64, 64);
}
self.insert_u64(other.state[l - 1], position + (l - 1) * 64, length % 64);
}
self.size = max(size_before_insertion, position + length);
}
pub fn insert_u64(&mut self, value: u64, position: usize, length: usize) {
let idx = position >> 6;
let offset = position % 64;
if 1 + ((position + length - 1) >> 6) > self.state.len() {
let num_seg = 1 + ((position + length - 1) >> 6) - self.state.len();
for _ in 0..num_seg {
self.state.push(0);
}
}
self.size = max(self.size, position + length);
if offset == 0 && length == 64 {
self.state[idx] = value;
} else if offset + length - 1 < 64 {
let mut u = u64::max_value();
u ^= ((1 << length) - 1) << offset;
self.state[idx] &= u;
self.state[idx] |= value << offset;
} else {
let lsb = (value & ((1 << (64 - offset)) - 1)) << offset;
let mask_lsb = u64::max_value() >> (64 - offset);
let msb = value >> (64 - offset);
let mask_msb = u64::max_value() << ((position + length) % 64);
self.state[idx] = (self.state[idx] & mask_lsb) | lsb;
self.state[idx + 1] = (self.state[idx + 1] & mask_msb) | msb;
}
}
pub fn reverse(&self) -> Self {
let mut state = vec![];
for &s in &self.state {
let bs = DenseBitSet::from_integer(s).reverse().to_integer();
state.push(bs);
}
state.reverse();
Self {
state,
size: self.size,
}
}
pub fn rotl(self, shift: usize) -> Self {
let shift_amount = shift % self.size;
let size_before_shift = self.size;
if shift_amount == 0 {
return self;
}
let mut shifted = (self.clone() << shift).subset(0, size_before_shift);
let extra = self.subset(size_before_shift - shift_amount, shift_amount);
shifted.insert(&extra, 0, shift_amount);
shifted
}
pub fn rotr(self, shift: usize) -> Self {
let shift_amount = shift % self.size;
let size_before_shift = self.size;
if shift_amount == 0 {
return self;
}
let extra = self.subset(0, shift_amount);
let mut shifted = self >> shift_amount;
shifted.insert(&extra, size_before_shift - shift_amount, shift_amount);
shifted
}
pub fn from_string(s: String, radix: u32) -> Self {
assert!(
radix.is_power_of_two(),
"Only power of two radices are supported"
);
assert!(radix > 1, "Radix must be > 1");
assert!(radix <= 32, "Radix must be <= 32");
let log_radix = u64::from(radix).trailing_zeros();
let chunk_size = 64 / log_radix as usize;
let mut size = 0;
let mut state = vec![];
let mut cur = s;
while !cur.is_empty() {
if cur.len() > chunk_size {
let (ms, ls) = cur.split_at(cur.len() - chunk_size);
let val = u64::from_str_radix(ls, radix).expect("Error while parsing input.");
state.push(val);
cur = String::from(ms);
size += 64;
} else {
let val = u64::from_str_radix(&cur.to_string(), radix)
.expect("Error while parsing input.");
state.push(val);
size += cur.len() * (log_radix as usize);
break;
}
}
Self { state, size }
}
pub fn first_set(&self) -> usize {
for i in 0..self.state.len() {
let cur = self.state[i];
if cur != 0 {
return i * 64 + (cur.trailing_zeros() as usize);
}
}
self.size
}
fn get(&self, index: usize) -> u64 {
match index {
u if u < self.state.len() => self.state[u],
_ => 0,
}
}
}
impl BitSet for DenseBitSetExtended {
fn set_bit(&mut self, position: usize, value: bool) {
let idx = position >> 6;
let offset = position % 64;
assert!(
idx < 1000,
"(Temporary?) We don't allow bitsets larger than 64k for now."
);
if idx >= self.state.len() {
if value {
for _ in 0..=(idx - self.state.len()) {
self.state.push(0);
}
self.state[idx] |= 1 << offset
}
} else if value {
self.state[idx] |= 1 << offset
} else {
self.state[idx] &= !(1 << offset)
}
if position >= self.size {
self.size = position + 1;
}
}
fn get_bit(&self, position: usize) -> bool {
if position > self.size {
return false;
}
let idx = position >> 6;
let offset = position % 64;
(self.state[idx] >> offset) & 1 == 1
}
fn get_weight(&self) -> u32 {
let mut hw = 0;
for &s in &self.state {
hw += s.count_ones();
}
hw
}
fn reset(&mut self) {
self.state = vec![];
self.size = 0
}
fn to_string(self) -> String {
if self.state.is_empty() {
return format!("{:064b}", 0);
}
let mut bss = vec![];
if self.size % 64 == 0 {
for s in self.state {
bss.push(format!("{:064b}", s));
}
} else {
for i in 0..self.state.len() - 1 {
bss.push(format!("{:064b}", self.state[i]));
}
bss.push(format!(
"{:064b}",
self.state[self.state.len() - 1] & ((1 << (self.size % 64)) - 1)
));
}
bss.reverse();
bss.join("")
}
}
impl fmt::Debug for DenseBitSetExtended {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut bss = String::new();
for i in 0..self.state.len() {
for j in 0..64 {
bss += if self.get_bit((self.state.len() - i - 1) * 64 + (63 - j)) {
"1"
} else {
"0"
};
}
}
write!(f, "0b{}", bss)
}
}
impl PartialEq for DenseBitSetExtended {
fn eq(&self, other: &Self) -> bool {
if self.size != other.size {
return false;
}
for i in 0..self.state.len() {
if self.state[i] != other.state[i] {
return false;
}
}
true
}
}
impl Hash for DenseBitSetExtended {
fn hash<H: Hasher>(&self, state: &mut H) {
for s in &self.state {
s.hash(state);
}
}
}
impl Eq for DenseBitSetExtended {}
impl Not for DenseBitSetExtended {
type Output = Self;
fn not(self) -> Self {
let l = self.state.len();
let mut inv = Self {
state: Vec::with_capacity(l),
size: self.size,
};
for i in 0..l - 1 {
inv.state.push(!self.state[i])
}
if self.size % 64 == 0 {
inv.state.push(!self.state[l - 1]);
} else {
inv.state
.push((!self.state[l - 1]) & ((1 << (self.size % 64)) - 1));
}
inv
}
}
impl BitAnd for DenseBitSetExtended {
type Output = Self;
fn bitand(self, rhs: Self) -> Self {
let l = min(self.state.len(), rhs.state.len());
let mut v = Vec::with_capacity(l);
for i in 0..l {
v.push(self.state[i] & rhs.state[i])
}
Self {
state: v,
size: min(self.size, rhs.size),
}
}
}
impl BitAndAssign for DenseBitSetExtended {
fn bitand_assign(&mut self, rhs: Self) {
let l = min(self.state.len(), rhs.state.len());
for i in 0..l {
self.state[i] &= rhs.state[i];
}
self.size = min(self.size, rhs.size);
}
}
impl BitOr for DenseBitSetExtended {
type Output = Self;
fn bitor(self, rhs: Self) -> Self {
let l = max(self.state.len(), rhs.state.len());
let mut v = Vec::with_capacity(l);
for i in 0..l {
if i < self.state.len() && i < rhs.state.len() {
v.push(self.state[i] | rhs.state[i])
} else if i >= self.state.len() {
v.push(rhs.state[i])
} else {
v.push(self.state[i])
}
}
Self {
state: v,
size: max(self.size, rhs.size),
}
}
}
impl BitOrAssign for DenseBitSetExtended {
fn bitor_assign(&mut self, rhs: Self) {
let l = max(self.state.len(), rhs.state.len());
for i in 0..l {
if i < self.state.len() && i < rhs.state.len() {
self.state[i] |= rhs.state[i]
} else if i >= self.state.len() {
self.state[i] = rhs.state[i]
}
}
}
}
impl BitXor for DenseBitSetExtended {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self {
let l = max(self.state.len(), rhs.state.len());
let mut v = Vec::with_capacity(l);
for i in 0..l {
if i < self.state.len() && i < rhs.state.len() {
v.push(self.state[i] ^ rhs.state[i])
} else if i >= self.state.len() {
v.push(rhs.state[i])
} else {
v.push(self.state[i])
}
}
Self {
state: v,
size: max(self.size, rhs.size),
}
}
}
impl BitXorAssign for DenseBitSetExtended {
fn bitxor_assign(&mut self, rhs: Self) {
let l = max(self.state.len(), rhs.state.len());
for i in 0..l {
if i < self.state.len() && i < rhs.state.len() {
self.state[i] ^= rhs.state[i]
} else if i >= self.state.len() {
self.state[i] = rhs.state[i]
}
}
}
}
impl Shl<usize> for DenseBitSetExtended {
type Output = Self;
fn shl(self, rhs: usize) -> Self {
let mut v = DenseBitSetExtended::with_capacity(self.size + rhs);
for i in 0..self.size {
let source = i;
let dest = i + rhs;
v.set_bit(dest, self.get_bit(source));
}
v
}
}
impl ShlAssign<usize> for DenseBitSetExtended {
fn shl_assign(&mut self, rhs: usize) {
let trailing_zeros = rhs >> 6;
let actual_shift = rhs % 64;
if rhs > (self.state.len() * 64 - self.size) {
self.state.push(0);
}
let l = self.state.len();
for i in 0..(l - 1) {
self.state[l - i - 1] = (self.state[l - i - 1] << actual_shift)
| (self.state[l - i - 2] >> (64 - actual_shift))
}
self.state[0] <<= actual_shift;
for _ in 0..trailing_zeros {
self.state.insert(0, 0);
}
self.size += rhs;
}
}
impl Shr<usize> for DenseBitSetExtended {
type Output = Self;
fn shr(self, rhs: usize) -> Self {
if rhs >= self.size {
Self {
state: vec![],
size: 0,
}
} else {
let mut v = DenseBitSetExtended::with_capacity(self.size - rhs);
for i in 0..(self.size - rhs) {
let source = i + rhs;
let dest = i;
v.set_bit(dest, self.get_bit(source));
}
v
}
}
}
impl ShrAssign<usize> for DenseBitSetExtended {
fn shr_assign(&mut self, rhs: usize) {
if rhs >= self.size {
self.reset();
}
let to_drop = rhs >> 6;
let actual_shift = rhs % 64;
for _ in 0..to_drop {
self.state.remove(0);
}
let l = self.state.len();
for i in 0..(l - 1) {
self.state[i] =
(self.state[i] >> actual_shift) | (self.state[i + 1] << (64 - actual_shift))
}
self.state[l - 1] >>= actual_shift;
self.size -= rhs;
}
}