Commit 37fce0ea authored by SirBlueRabbit's avatar SirBlueRabbit
Browse files

fixed depth bug

parent 8a2c6c6c
......@@ -315,7 +315,23 @@ impl<V> Pool<Node<V>> {
u_d_depth.abs_diff(p_d_depth)
}
} else {
u_d_depth.abs_diff(p_d_depth)
match self.child_type(u) {
ChildType::Left => {
if self[p].d_flip {
u_d_depth + p_d_depth
} else {
u_d_depth.abs_diff(p_d_depth)
}
}
ChildType::Right => {
if self[p].d_flip {
u_d_depth.abs_diff(p_d_depth)
} else {
u_d_depth + p_d_depth
}
}
_ => unreachable!(),
}
};
if let Some(x) = x_opt {
......@@ -649,7 +665,107 @@ mod tests {
}
#[test]
fn random_scan() {
fn rotate_depth() {
// create lct
let mut lct = Pool::with_capacity(2);
let a = lct.add_node("a");
let b = lct.add_node("b");
// link nodes
lct.link(a, b);
// rotate parent
lct.rotate(a);
// check depth
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
}
#[test]
fn splay_depth() {
// create lct
let mut lct = Pool::with_capacity(3);
let a = lct.add_node("a");
let b = lct.add_node("b");
let c = lct.add_node("c");
// link and expose
lct.link(a, b);
lct.link(b, c);
lct.splay(b);
lct.splay(a);
lct.splay(c);
// check depths
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
assert_eq!(lct.depth(c), 2);
}
#[test]
fn expose_depth() {
// crate lct
let mut lct = Pool::with_capacity(3);
let a = lct.add_node("a");
let b = lct.add_node("b");
let c = lct.add_node("c");
// link and expose
lct.link(a, b);
lct.link(b, c);
lct.expose(b);
lct.expose(a);
//lct.expose(c);
lct.splay(c);
if let Some(child) = lct[c].children[ChildType::from(true)] {
lct[child].parent = Parent::Path(c);
lct[c].children[ChildType::from(true)] = None;
}
while let Parent::Path(p) = lct[c].parent {
lct.splay(p);
// check depths
println!("after splaying {p}:");
dbg!(&lct);
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
assert_eq!(lct.depth(c), 2);
if let Some(x) = lct[p].children[ChildType::from(true)] {
lct[x].parent = Parent::Path(p);
}
lct[p].children[ChildType::from(true)] = Some(c);
lct[c].parent = Parent::BinTree(p);
// check depths
println!("after reassigning children of {p}:");
dbg!(&lct);
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
assert_eq!(lct.depth(c), 2);
lct.rotate(c);
// check depths
println!("after rotating {c}:");
dbg!(&lct);
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
assert_eq!(lct.depth(c), 2);
}
// check depths
dbg!(&lct);
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
assert_eq!(lct.depth(c), 2);
}
#[test]
fn random_evert() {
// generate a basic lct
let size = 3;
let mut lct = Pool::with_capacity(size);
......@@ -662,22 +778,53 @@ mod tests {
lct.link(parent, child);
}
// randomly mutate lct and check integrity
// randomly evert
for _ in 0..(size * size * size) {
let root = Label::from(fastrand::usize(0..size));
lct.evert(root);
let label = Label::from(fastrand::usize(0..size));
lct.expose(label);
assert_clean(&lct);
assert_depth(&lct, label);
}
}
#[test]
fn random_cut_link() {
// generate a basic lct
let size = 5;
let mut lct = Pool::with_capacity(size);
for i in 0..size {
let _ = lct.add_node(i);
}
for i in 0..(size - 1) {
let parent = Label::from(i);
let child = Label::from(i + 1);
lct.link(parent, child);
}
// randomly cut and link
for _ in 0..(size * size * size) {
let label1 = Label::from(fastrand::usize(0..size));
let label2 = Label::from(fastrand::usize(0..size));
if label1 != label2 {
dbg!(&lct);
// evert
dbg!(&label1);
lct.evert(label1);
dbg!(&lct);
// expose
dbg!(&label2);
lct.expose(label2);
dbg!(&lct);
dbg!(label1);
dbg!(label2);
let depth = lct.depth(label2);
assert_depth(&lct, label2);
// find a node to cut
let depth = lct.depth(label2);
let index = fastrand::usize(0..depth);
let cut = lct.index_depth(label2, index + 1);
// cut and link back
lct.cut(cut);
lct.evert(label2);
lct.link(label1, label2);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment