use crate::def::*;
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct Bset(pub u128, pub u128);
impl Debug for Bset {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ll(*self).fmt(f)
}
}
fn ll(set: Bset) -> Vec<(u8, u8)> {
let mut sink = vec![];
for i in set.get() {
if let Some((_, b)) = sink.last_mut() {
if *b == i - 1 {
*b += 1;
continue;
}
}
sink.push((i, i));
}
sink
}
fn tolist(i: u128, offset: u8, sink: &mut Vec<(u8, u8)>) {
for j in 0..128 {
if 0 != ((i >> j) & 1) {
if let Some((_, b)) = sink.last_mut() {
if *b == (j + offset) - 1 {
*b += 1;
continue;
}
}
sink.push((j, j));
}
}
}
pub fn brange(a: u128, b: u128) -> u128 {
let hi = !0 >> (127 - b);
let lo = (1 << a) - 1;
hi ^ lo
}
impl Bset {
pub fn getb(self) -> [bool; 256] {
let mut e = [false; 256];
for (o, i) in [self.0, self.1].iter().enumerate() {
let o = o * 128;
for j in 0..128 {
e[(j + o)] = 0 != ((i >> j) & 1);
}
}
e
}
pub fn pairs(self) -> Vec<(u8, u8)> {
let mut e = vec![];
tolist(self.0, 000, &mut e);
tolist(self.1, 128, &mut e);
e
}
pub fn get(self) -> Vec<u8> {
self.getb()
.iter()
.enumerate()
.filter(|x| *x.1)
.map(|x| x.0 as u8)
.collect()
}
pub fn range(a: char, b: char) -> Bset {
Bset::brange(a as u8, b as u8)
}
pub fn brange(a: u8, b: u8) -> Bset {
let a = a as u128;
let b = b as u128;
let llo = if a < 128 { brange(a, b.min(127)) } else { 0 };
let hhi = if b >= 128 {
brange(a.max(128) - 128, b.max(128) - 128)
} else {
0
};
Bset(llo, hhi)
}
pub fn fromchar(a: char) -> Bset {
Bset::range(a, a)
}
pub fn frombyte(a: u8) -> Bset {
Bset::brange(a, a)
}
pub fn str(s: &str) -> Bset {
s.as_bytes()
.iter()
.fold(Bset(0, 0), |a, b| a | Bset::frombyte(*b))
}
}
impl Not for Bset {
type Output = Bset;
fn not(self) -> Bset {
let l = self;
Bset(!l.0, !l.1)
}
}
impl BitOr for Bset {
type Output = Self;
fn bitor(self, r: Bset) -> Bset {
let l = self;
Bset(l.0 | r.0, l.1 | r.1)
}
}
impl BitOrAssign for Bset {
fn bitor_assign(&mut self, r: Bset) {
*self = *self | r;
}
}
impl BitAnd for Bset {
type Output = Self;
fn bitand(self, r: Bset) -> Bset {
let l = self;
Bset(l.0 & r.0, l.1 & r.1)
}
}
impl BitXor for Bset {
type Output = Self;
fn bitxor(self, r: Bset) -> Bset {
let l = self;
Bset(l.0 ^ r.0, l.1 ^ r.1)
}
}