use pace26io::{binary_tree::*, newick::NewickWriter, pace::simplified::*};
type Builder = IndexedBinTreeBuilder; type Node = <Builder as TreeBuilder>::Node;
fn main() {
let mut tree_builder = Builder::default();
let instance = Instance::try_read(&mut std::io::stdin().lock(), &mut tree_builder)
.expect("Valid PACE26 Instance");
println!("# Found {} trees", instance.trees.len());
if let Some(td) = instance.tree_decomposition.as_ref() {
println!(
"# Found tree decomposition with treewidth {}, {} bags, and {} edges",
td.treewidth,
td.bags.len(),
td.edges.len()
);
}
for (tree_id, tree) in instance.trees.iter().enumerate() {
let root_id = (tree_id + 1) * (instance.num_leaves - 1) + 2;
let normalized_tree =
build_normalized_tree(&mut tree_builder, tree, NodeIdx(root_id as u32));
println!("{}", normalized_tree.top_down().to_newick_string());
}
}
fn build_normalized_tree(
builder: &mut Builder,
node: impl TopDownCursor,
node_id: NodeIdx,
) -> Node {
let root = build_normalized_tree_rec(builder, node, node_id).0;
builder.make_root(root)
}
fn build_normalized_tree_rec(
builder: &mut Builder,
node: impl TopDownCursor,
node_id: NodeIdx,
) -> (Node, Label, NodeIdx) {
match node.visit() {
NodeType::Leaf(label) => (builder.new_leaf(label), label, node_id),
NodeType::Inner(left, right) => {
let (child0, label0, next_node_id) =
build_normalized_tree_rec(builder, left, node_id.incremented());
let (child1, label1, next_node_id) =
build_normalized_tree_rec(builder, right, next_node_id);
if label0 < label1 {
(
builder.new_inner(node_id, child0, child1),
label0,
next_node_id,
)
} else {
(
builder.new_inner(node_id, child1, child0),
label1,
next_node_id,
)
}
}
}
}