use succinctly::{BitVec, RankSelect};
fn bitread(s: &str) -> BitVec {
let bits: Vec<bool> = s
.chars()
.filter(|c| *c == '0' || *c == '1')
.map(|c| c == '1')
.collect();
if bits.is_empty() {
return BitVec::new();
}
let num_words = bits.len().div_ceil(64);
let mut words = vec![0u64; num_words];
for (i, &bit) in bits.iter().enumerate() {
if bit {
let word_idx = i / 64;
let bit_idx = i % 64;
words[word_idx] |= 1u64 << bit_idx;
}
}
BitVec::from_words(words, bits.len())
}
#[test]
fn test_rank1_pattern_10010010() {
let bv = bitread("10010010");
assert_eq!(bv.len(), 8);
assert_eq!(bv.count_ones(), 3);
let expected = [0, 1, 1, 1, 2, 2, 2, 3, 3];
for (i, &exp) in expected.iter().enumerate() {
assert_eq!(bv.rank1(i), exp, "rank1({}) mismatch", i);
}
}
#[test]
fn test_rank1_pattern_11011010_00000000() {
let bv = bitread("11011010 00000000");
assert_eq!(bv.len(), 16);
assert_eq!(bv.count_ones(), 5);
let expected = [0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5];
for (i, &exp) in expected.iter().enumerate() {
assert_eq!(bv.rank1(i), exp, "rank1({}) mismatch", i);
}
}
#[test]
fn test_rank1_pattern_11011010_10000000() {
let bv = bitread("11011010 10000000");
assert_eq!(bv.len(), 16);
assert_eq!(bv.count_ones(), 6);
let expected = [0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6];
for (i, &exp) in expected.iter().enumerate() {
assert_eq!(bv.rank1(i), exp, "rank1({}) mismatch", i);
}
}
#[test]
fn test_select1_pattern_10010010() {
let bv = bitread("10010010");
assert_eq!(bv.select1(0), Some(0));
assert_eq!(bv.select1(1), Some(3));
assert_eq!(bv.select1(2), Some(6));
assert_eq!(bv.select1(3), None);
}
#[test]
fn test_select1_pattern_11011010() {
let bv = bitread("11011010");
assert_eq!(bv.select1(0), Some(0));
assert_eq!(bv.select1(1), Some(1));
assert_eq!(bv.select1(2), Some(3));
assert_eq!(bv.select1(3), Some(4));
assert_eq!(bv.select1(4), Some(6));
assert_eq!(bv.select1(5), None);
}
#[test]
fn test_select1_pattern_01000000_00000100() {
let bv = bitread("01000000 00000100");
assert_eq!(bv.select1(0), Some(1));
assert_eq!(bv.select1(1), Some(13));
assert_eq!(bv.select1(2), None);
}
#[test]
fn test_select1_pattern_across_bytes() {
let bv = bitread("11000001 10000000 01000000");
assert_eq!(bv.select1(0), Some(0));
assert_eq!(bv.select1(1), Some(1));
assert_eq!(bv.select1(2), Some(7));
assert_eq!(bv.select1(3), Some(8));
assert_eq!(bv.select1(4), Some(17));
}
#[test]
fn test_select1_pattern_32bits() {
let bv = bitread("10000010 00000000 00100000 00010000");
assert_eq!(bv.select1(0), Some(0));
assert_eq!(bv.select1(1), Some(6));
assert_eq!(bv.select1(2), Some(18));
assert_eq!(bv.select1(3), Some(27));
assert_eq!(bv.select1(4), None);
}
#[test]
fn test_roundtrip_various_patterns() {
let patterns = [
"10010010",
"11111111",
"00000000",
"10101010",
"01010101",
"11110000",
"00001111",
"11011010 00000000",
"11011010 10000000",
"01000000 00000100",
"10000010 00000000 00100000 00010000",
];
for pattern in patterns {
let bv = bitread(pattern);
for k in 0..bv.count_ones() {
let pos = bv.select1(k).unwrap();
assert!(
bv.get(pos),
"pattern '{}': select1({}) = {} but bit is not set",
pattern,
k,
pos
);
assert_eq!(
bv.rank1(pos + 1),
k + 1,
"pattern '{}': rank1(select1({}) + 1) != {} + 1",
pattern,
k,
k
);
}
}
}
#[test]
fn test_long_alternating_pattern() {
let pattern: String = "10".repeat(2048);
let bv = bitread(&pattern);
assert_eq!(bv.len(), 4096);
assert_eq!(bv.count_ones(), 2048);
for x in 1..=4096 {
let expected = (x - 1) / 2 + 1;
assert_eq!(bv.rank1(x), expected, "rank1({}) mismatch", x);
}
}
#[test]
fn test_long_sparse_pattern() {
let mut pattern = String::new();
for _ in 0..64 {
pattern.push('1');
pattern.push_str(&"0".repeat(63));
}
let bv = bitread(&pattern);
assert_eq!(bv.len(), 4096);
assert_eq!(bv.count_ones(), 64);
for k in 0..64 {
assert_eq!(bv.select1(k), Some(k * 64), "select1({}) mismatch", k);
}
}
#[test]
fn test_empty_bitvector() {
let bv = bitread("");
assert_eq!(bv.len(), 0);
assert_eq!(bv.count_ones(), 0);
assert_eq!(bv.rank1(0), 0);
assert_eq!(bv.select1(0), None);
}
#[test]
fn test_single_one() {
let bv = bitread("1");
assert_eq!(bv.len(), 1);
assert_eq!(bv.count_ones(), 1);
assert_eq!(bv.rank1(0), 0);
assert_eq!(bv.rank1(1), 1);
assert_eq!(bv.select1(0), Some(0));
assert_eq!(bv.select1(1), None);
}
#[test]
fn test_single_zero() {
let bv = bitread("0");
assert_eq!(bv.len(), 1);
assert_eq!(bv.count_ones(), 0);
assert_eq!(bv.rank1(0), 0);
assert_eq!(bv.rank1(1), 0);
assert_eq!(bv.select1(0), None);
}