diff --git a/2021/rust/Cargo.toml b/2021/rust/Cargo.toml index 21ec09e..e3bfc15 100644 --- a/2021/rust/Cargo.toml +++ b/2021/rust/Cargo.toml @@ -12,4 +12,8 @@ path = "day16.rs" name = "day17" path = "day17.rs" +[[bin]] +name = "day18" +path = "day18.rs" + [dependencies] diff --git a/2021/rust/day18.rs b/2021/rust/day18.rs new file mode 100644 index 0000000..765a5df --- /dev/null +++ b/2021/rust/day18.rs @@ -0,0 +1,99 @@ +#![warn(clippy::all, clippy::pedantic)] + +mod common; +use common::day_input; + +type ChildNode = Box>; + +#[derive(Debug, std::cmp::PartialEq)] +struct BinaryTreeBranch { + left: ChildNode, + right: ChildNode, +} + +#[derive(Debug, std::cmp::PartialEq)] +enum BinaryTreeNode { + Branch(BinaryTreeBranch), + Leaf(T), +} + +fn crawl_for(node: &BinaryTreeNode, predicate: fn(&BinaryTreeNode, u64) -> bool, current_depth: u64) -> Option<&BinaryTreeNode> { + if predicate(node, current_depth) { + Some(node) + } else if let BinaryTreeNode::Branch(branch) = node { + if let Some(result) = crawl_for(&*branch.left, predicate, current_depth + 1) { + Some(result) + } else if let Some(result) = crawl_for(&*branch.right, predicate, current_depth + 1) { + Some(result) + } else { + None + } + } else { + None + } +} + +fn maybe_explode(tree: &mut BinaryTreeNode) -> bool { + if let Some(node_to_explode) = crawl_for(tree, |node, d| { + if let BinaryTreeNode::Branch(_) = node { + // TODO: must both child nodes be leaves? + d >= 3 + } else { + false + } + }, 0) { + // TODO: do explosion + println!("{:#?}", node_to_explode); + true + } else { + false + } +} + +fn parse_binary_tree(s: &str) -> Result, &'static str> { + let chars = s.chars().peekable(); + let ch = chars.peek(); + if let Some(c) = ch { + match c { + '0'..='9' => Ok(BinaryTreeNode::Leaf(u64::from(*c) - ASCII_0)) + '[' => { + it.next() + parse_binary_tree( + // TODO: parse left piece + // TODO: parse right piece + // do_parse_binary_tree(&s[1..], depth + 1) + // TODO: parse end of this (']') + } + _ => Err("unknown char") + } + } else { + Err("empty string") + } +} + +fn main() { + let result = parse_binary_tree(&day_input(18)); + println!("Snailfish Homework: {:#?}", result); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parser() { + assert_eq!(parse_binary_tree("y"), Err("unknown char")); + assert_eq!(parse_binary_tree("9"), Ok(BinaryTreeNode::Leaf(9))); + assert_eq!(parse_binary_tree("[[1,2],3]"), Ok(BinaryTreeNode::Branch(BinaryTreeBranch { + left: Box::new(BinaryTreeNode::Branch(BinaryTreeBranch { + left: Box::new(BinaryTreeNode::Leaf(1)), + right: Box::new(BinaryTreeNode::Leaf(2)), + })), + right: Box::new(BinaryTreeNode::Leaf(3)), + }))); + } + + #[test] + fn needs_exploding() { + } +}