···
1
+
use std::collections::VecDeque;
10
+
ThreeNode(ThreeNode),
14
+
// Wrap Rc in a single-value enum so I can implement traits for it.
20
+
pub struct TwoNode {
23
+
children: (DnaRef, DnaRef),
27
+
pub struct ThreeNode {
30
+
children: (DnaRef, DnaRef, DnaRef),
35
+
Two(DnaRef, DnaRef),
39
+
pub fn new() -> Self {
40
+
Self::DnaRef(Rc::new(Dna::Empty))
43
+
fn from_char(c: char) -> Self {
44
+
Self::DnaRef(Rc::new(Dna::Leaf(c)))
47
+
fn from_two_children(a: DnaRef, b: DnaRef) -> Self {
48
+
debug_assert_eq!(a.depth(), b.depth());
49
+
Self::DnaRef(Rc::new(Dna::TwoNode(TwoNode {
50
+
len: a.len() + b.len(),
51
+
depth: a.depth() + 1,
56
+
fn from_three_children(a: DnaRef, b: DnaRef, c: DnaRef) -> Self {
57
+
debug_assert_eq!(a.depth(), b.depth());
58
+
debug_assert_eq!(a.depth(), c.depth());
59
+
Self::DnaRef(Rc::new(Dna::ThreeNode(ThreeNode {
60
+
len: a.len() + b.len() + c.len(),
61
+
depth: a.depth() + 1,
62
+
children: (a, b, c),
66
+
pub fn from_string(s: &str) -> Self {
67
+
s.chars().map(|c| DnaRef::from_char(c)).collect::<DnaRef>()
70
+
pub fn len(&self) -> usize {
74
+
Dna::TwoNode(node) => node.len,
75
+
Dna::ThreeNode(node) => node.len,
79
+
pub fn depth(&self) -> usize {
83
+
Dna::TwoNode(node) => node.depth,
84
+
Dna::ThreeNode(node) => node.depth,
88
+
// Use Index trait instead
89
+
pub fn index(&self, n: usize) -> char {
90
+
debug_assert!(n < self.len());
93
+
Dna::Empty => unreachable!(),
95
+
Dna::TwoNode(node) => {
96
+
let (a, b) = &node.children;
100
+
b.index(n - a.len())
103
+
Dna::ThreeNode(node) => {
104
+
let (a, b, c) = &node.children;
107
+
} else if n < a.len() + b.len() {
108
+
b.index(n - a.len())
110
+
c.index(n - a.len() - b.len())
116
+
pub fn split(&self, n: usize) -> (DnaRef, DnaRef) {
117
+
debug_assert!(n <= self.len());
119
+
Dna::Empty => (Self::new(), Self::new()),
122
+
(Self::new(), Self::from_char(*c))
124
+
(Self::from_char(*c), Self::new())
127
+
Dna::TwoNode(node) => {
128
+
let (a, b) = &node.children;
130
+
let (x, y) = a.split(n);
131
+
(x, Self::concat(y, b.clone()))
132
+
} else if n == a.len() {
133
+
(a.clone(), b.clone())
135
+
let (x, y) = b.split(n - a.len());
136
+
(Self::concat(a.clone(), x), y)
139
+
Dna::ThreeNode(node) => {
140
+
let (a, b, c) = &node.children;
142
+
let (x, y) = a.split(n);
143
+
(x, Self::concat(Self::concat(y, b.clone()), c.clone()))
144
+
} else if n == a.len() {
145
+
(a.clone(), Self::concat(b.clone(), c.clone()))
146
+
} else if n - a.len() < b.len() {
147
+
let (x, y) = b.split(n - a.len());
148
+
(Self::concat(a.clone(), x), Self::concat(y, c.clone()))
149
+
} else if n == a.len() + b.len() {
150
+
(Self::concat(a.clone(), b.clone()), c.clone())
152
+
let (x, y) = c.split(n - a.len() - b.len());
153
+
(Self::concat(a.clone(), Self::concat(b.clone(), x)), y)
159
+
fn concat_helper(lhs: DnaRef, rhs: DnaRef) -> ConcatState {
160
+
if lhs.depth() == rhs.depth() {
161
+
ConcatState::Two(lhs, rhs)
162
+
} else if lhs.depth() < rhs.depth() {
164
+
Dna::Empty => unreachable!(),
165
+
Dna::Leaf(_) => unreachable!(),
166
+
Dna::TwoNode(node) => {
167
+
let (a, b) = &node.children;
168
+
match Self::concat_helper(lhs, a.clone()) {
169
+
ConcatState::One(x) => {
170
+
ConcatState::One(Self::from_two_children(x, b.clone()))
172
+
ConcatState::Two(x, y) => {
173
+
ConcatState::One(Self::from_three_children(x, y, b.clone()))
177
+
Dna::ThreeNode(node) => {
178
+
let (a, b, c) = &node.children;
179
+
match Self::concat_helper(lhs, a.clone()) {
180
+
ConcatState::One(x) => {
181
+
ConcatState::One(Self::from_three_children(x, b.clone(), c.clone()))
183
+
ConcatState::Two(x, y) => ConcatState::Two(
184
+
Self::from_two_children(x, y),
185
+
Self::from_two_children(b.clone(), c.clone()),
192
+
Dna::Empty => unreachable!(),
193
+
Dna::Leaf(_) => unreachable!(),
194
+
Dna::TwoNode(node) => {
195
+
let (a, b) = &node.children;
196
+
match Self::concat_helper(b.clone(), rhs) {
197
+
ConcatState::One(x) => {
198
+
ConcatState::One(Self::from_two_children(a.clone(), x))
200
+
ConcatState::Two(x, y) => {
201
+
ConcatState::One(Self::from_three_children(a.clone(), x, y))
205
+
Dna::ThreeNode(node) => {
206
+
let (a, b, c) = &node.children;
207
+
match Self::concat_helper(c.clone(), rhs) {
208
+
ConcatState::One(x) => {
209
+
ConcatState::One(Self::from_three_children(a.clone(), b.clone(), x))
211
+
ConcatState::Two(x, y) => ConcatState::Two(
212
+
Self::from_two_children(a.clone(), b.clone()),
213
+
Self::from_two_children(x, y),
221
+
// Use Add trait instead
222
+
pub fn concat(lhs: DnaRef, rhs: DnaRef) -> Self {
223
+
match Self::concat_helper(lhs, rhs) {
224
+
ConcatState::One(a) => a,
225
+
ConcatState::Two(a, b) => Self::from_two_children(a, b),
229
+
pub fn iter<'a>(&'a self) -> DnaIterator<'a> {
230
+
let mut stack = Vec::new();
232
+
DnaIterator { stack }
236
+
impl Deref for DnaRef {
239
+
fn deref(&self) -> &Self::Target {
241
+
DnaRef::DnaRef(r) => &*r,
246
+
struct DnaRefIter<I>
248
+
I: Iterator<Item = DnaRef>,
251
+
buf: VecDeque<DnaRef>,
254
+
impl<I> DnaRefIter<I>
256
+
I: Iterator<Item = DnaRef>,
258
+
fn new(iter: I) -> DnaRefIter<I> {
261
+
buf: VecDeque::with_capacity(5),
266
+
impl<I> Iterator for DnaRefIter<I>
268
+
I: Iterator<Item = DnaRef>,
270
+
type Item = DnaRef;
271
+
fn next(&mut self) -> Option<Self::Item> {
272
+
while self.buf.len() < 5 {
273
+
let Some(x) = self.iter.next() else {
277
+
self.buf.push_back(x);
280
+
if self.buf.len() == 5 || self.buf.len() == 3 {
281
+
let a = self.buf.pop_front().unwrap();
282
+
let b = self.buf.pop_front().unwrap();
283
+
let c = self.buf.pop_front().unwrap();
285
+
return Some(DnaRef::from_three_children(a, b, c));
286
+
} else if self.buf.len() == 4 || self.buf.len() == 2 {
287
+
let a = self.buf.pop_front().unwrap();
288
+
let b = self.buf.pop_front().unwrap();
290
+
return Some(DnaRef::from_two_children(a, b));
297
+
impl FromIterator<DnaRef> for DnaRef {
298
+
fn from_iter<I: IntoIterator<Item = DnaRef>>(iter: I) -> DnaRef {
299
+
// We need some kind of buffer no matter what, even if we aggregate as we go.
300
+
// This implementation does the easy thing and just repeatedly collects into a Vec.
301
+
let mut cur: Vec<DnaRef> = iter.into_iter().collect::<Vec<_>>();
302
+
while cur.len() > 1 {
303
+
cur = DnaRefIter::new(cur.into_iter()).collect();
306
+
return cur.pop().unwrap();
310
+
pub struct DnaIterator<'a> {
311
+
stack: Vec<&'a DnaRef>,
314
+
impl<'a> Iterator for DnaIterator<'a> {
317
+
fn next(&mut self) -> Option<Self::Item> {
318
+
while let Some(node) = self.stack.pop() {
320
+
Dna::Empty => return None,
321
+
Dna::Leaf(c) => return Some(*c),
322
+
Dna::TwoNode(node) => {
323
+
let (a, b) = &node.children;
324
+
self.stack.push(b);
325
+
self.stack.push(a);
327
+
Dna::ThreeNode(node) => {
328
+
let (a, b, c) = &node.children;
329
+
self.stack.push(c);
330
+
self.stack.push(b);
331
+
self.stack.push(a);
346
+
let dna: DnaRef = DnaRef::new();
347
+
assert_eq!(dna.len(), 0);
351
+
fn test_to_from_string() {
352
+
let dna: DnaRef = DnaRef::from_string("ICFP");
353
+
assert_eq!(dna.iter().collect::<String>(), "ICFP");
359
+
let dna: DnaRef = DnaRef::from_string(s);
360
+
for (i, c) in s.chars().enumerate() {
361
+
assert_eq!(dna.index(i), c);
367
+
let lhs = DnaRef::from_string("ABCD");
368
+
let rhs = DnaRef::from_string("WXYZ");
370
+
DnaRef::concat(lhs, rhs).iter().collect::<String>(),
377
+
let dna = DnaRef::from_string("ABCDWXYZ");
378
+
let (lhs, rhs) = dna.split(4);
379
+
assert_eq!(lhs.iter().collect::<String>(), "ABCD");
380
+
assert_eq!(rhs.iter().collect::<String>(), "WXYZ");