// Tree String โ 99 Problems #36
// Convert a binary tree to/from a string representation.
// Format: "a(b(d,e),c(,f))" โ Node(left,right), empty = ""
#[derive(Debug, PartialEq, Clone)]
enum Tree {
Leaf,
Node(Box<Tree>, char, Box<Tree>),
}
impl Tree {
fn leaf() -> Self { Tree::Leaf }
fn node(l: Tree, v: char, r: Tree) -> Self {
Tree::Node(Box::new(l), v, Box::new(r))
}
}
/// Convert tree to string.
fn tree_to_string(tree: &Tree) -> String {
match tree {
Tree::Leaf => String::new(),
Tree::Node(l, v, r) => {
match (l.as_ref(), r.as_ref()) {
(Tree::Leaf, Tree::Leaf) => v.to_string(),
_ => format!("{}({},{})", v, tree_to_string(l), tree_to_string(r)),
}
}
}
}
/// Parse a tree string back to Tree.
fn string_to_tree(s: &str) -> Tree {
parse(&s.chars().collect::<Vec<_>>(), &mut 0)
}
fn parse(chars: &[char], pos: &mut usize) -> Tree {
if *pos >= chars.len() || chars[*pos] == ',' || chars[*pos] == ')' {
return Tree::leaf();
}
let v = chars[*pos];
*pos += 1;
if *pos < chars.len() && chars[*pos] == '(' {
*pos += 1; // skip '('
let left = parse(chars, pos);
assert_eq!(chars[*pos], ',');
*pos += 1; // skip ','
let right = parse(chars, pos);
assert_eq!(chars[*pos], ')');
*pos += 1; // skip ')'
Tree::node(left, v, right)
} else {
Tree::node(Tree::leaf(), v, Tree::leaf())
}
}
fn sample_tree() -> Tree {
// a
// / \
// b c
// / \ \
// d e f
Tree::node(
Tree::node(
Tree::node(Tree::leaf(), 'd', Tree::leaf()),
'b',
Tree::node(Tree::leaf(), 'e', Tree::leaf()),
),
'a',
Tree::node(Tree::leaf(), 'c', Tree::node(Tree::leaf(), 'f', Tree::leaf())),
)
}
fn main() {
let t = sample_tree();
let s = tree_to_string(&t);
println!("Tree โ String: {}", s);
let parsed = string_to_tree(&s);
println!("String โ Tree: {:?}", parsed);
println!("Round-trip OK: {}", t == parsed);
println!("Single 'x': {}", tree_to_string(&Tree::node(Tree::leaf(), 'x', Tree::leaf())));
println!("Empty: '{}'", tree_to_string(&Tree::leaf()));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_leaf_to_string() {
assert_eq!(tree_to_string(&Tree::leaf()), "");
}
#[test]
fn test_single_node() {
let t = Tree::node(Tree::leaf(), 'x', Tree::leaf());
assert_eq!(tree_to_string(&t), "x");
}
#[test]
fn test_round_trip() {
let t = sample_tree();
let s = tree_to_string(&t);
assert_eq!(string_to_tree(&s), t);
}
#[test]
fn test_parse_single() {
let t = string_to_tree("x");
assert_eq!(t, Tree::node(Tree::leaf(), 'x', Tree::leaf()));
}
}
(* Tree String *)
(* OCaml 99 Problems #36 *)
(* Implementation for example 36 *)
(* Tests *)
let () =
(* Add tests *)
print_endline "โ OCaml tests passed"