1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use super::{Louds, LoudsBuilder};
use crate::succinct_bit_vector::SuccinctBitVectorBuilder;
use crate::BitString;
impl super::LoudsBuilder {
pub fn from_bit_string(bs: BitString) -> Self {
LoudsBuilder::validate_lbs(&bs);
let bv_builder = SuccinctBitVectorBuilder::from_bit_string(bs);
LoudsBuilder { bv_builder }
}
pub fn build(&self) -> Louds {
let bv = self.bv_builder.build();
Louds { lbs: bv }
}
fn validate_lbs(bs: &BitString) {
let s = bs.str();
assert!(s.starts_with("10"));
let (mut cnt0, mut cnt1) = (0u64, 0u64);
for (i, ch) in s.chars().enumerate() {
match ch {
'0' => cnt0 += 1,
'1' => cnt1 += 1,
c => panic!("LBS contains invalid character '{}'", c),
}
assert!(
cnt0 <= cnt1 + 1,
"At index {}, the number of '0' ({}) == (the number of '1' ({})) + 2.",
i,
cnt0,
cnt1,
);
}
assert_eq!(cnt0, cnt1 + 1);
}
}
#[cfg(test)]
mod validate_lbs_success_tests {
use crate::{BitString, LoudsBuilder};
macro_rules! parameterized_tests {
($($name:ident: $value:expr,)*) => {
$(
#[test]
fn $name() {
let s = $value;
let bs = BitString::new(s);
LoudsBuilder::validate_lbs(&bs);
}
)*
}
}
parameterized_tests! {
t1: "10_0",
t2: "10_10_0",
t3: "10_1110_10_0_1110_0_0_10_110_0_0_0",
t4: "10_11111111110_0_0_0_0_0_0_0_0_0_0",
}
}
#[cfg(test)]
mod validate_lbs_failure_tests {
use crate::{BitString, LoudsBuilder};
macro_rules! parameterized_tests {
($($name:ident: $value:expr,)*) => {
$(
#[test]
#[should_panic]
fn $name() {
let s = $value;
let bs = BitString::new(s);
LoudsBuilder::validate_lbs(&bs);
}
)*
}
}
parameterized_tests! {
t1: "0",
t2: "1",
t3: "00",
t4: "01",
t5: "10",
t6: "11",
t7: "00_0",
t8: "01_0",
t9: "11_0",
t10: "10_1",
t11: "10_10",
t12: "10_01",
t13: "10_1110_10_0_1110_0_0_10_110_0_0_1",
}
}