Day 18 part 1, STILL BROKEN.

This commit is contained in:
Bill Thiede 2020-12-18 22:40:22 -08:00
parent 3775e36fad
commit 7ee762858c

View File

@ -54,12 +54,17 @@ fn eval(ast: &Ast) -> u32 {
0
}
#[derive(Copy, Clone, Default, Debug)]
#[derive(Copy, Clone, Default, PartialEq)]
struct NodeId(usize);
impl fmt::Debug for NodeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "NodeId({})", self.0)
}
}
#[derive(Debug, Default)]
struct Node {
parent: NodeId,
parent: Option<NodeId>,
data: Option<Token>,
left: Option<NodeId>,
right: Option<NodeId>,
@ -81,14 +86,14 @@ impl Node {
#[derive(Debug)]
struct Tree {
nodes: Vec<Node>,
root: NodeId,
}
use std::fmt;
impl fmt::Display for Tree {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let cur = NodeId(0);
fn print_node(f: &mut fmt::Formatter<'_>, tree: &Tree, id: NodeId) -> fmt::Result {
//dbg!(id, tree.get_node(id));
match tree.get_node(id).data {
None => (),
Some(Token::Num(n)) => write!(f, "{}", n)?,
@ -114,13 +119,14 @@ impl fmt::Display for Tree {
};
Ok(())
}
print_node(f, self, cur)
print_node(f, self, self.root)
}
}
impl Default for Tree {
fn default() -> Tree {
Tree {
nodes: vec![Node::default()],
root: NodeId(0),
}
}
}
@ -138,7 +144,7 @@ impl Tree {
}
}
#[derive(Default)]
#[derive(Debug, Default)]
struct Parser {
tree: Tree,
cur: NodeId,
@ -147,13 +153,13 @@ struct Parser {
impl Parser {
fn add_left_child_cur(&mut self, mut n: Node) -> NodeId {
n.parent = self.cur;
n.parent = Some(self.cur);
let id = self.tree.add_node(n);
self.cur_node_mut().left = Some(id);
id
}
fn add_right_child_cur(&mut self, mut n: Node) -> NodeId {
n.parent = self.cur;
n.parent = Some(self.cur);
let id = self.tree.add_node(n);
self.cur_node_mut().right = Some(id);
id
@ -162,25 +168,68 @@ impl Parser {
self.tree.get_node_mut(self.cur)
}
fn parse(&mut self, tokens: &[Token]) {
self.debug_tokens = tokens.to_vec();
tokens.iter().for_each(|t| {
self.add_token(t);
});
fn cur_node(&self) -> &Node {
self.tree.get_node(self.cur)
}
fn set_cur_data(&mut self, t: &Token) {
let cur = self.cur_node();
let cur_id = self.cur;
if cur.data.is_some() {
match cur.right {
Some(node) => {
// Create a new node, stick it in `right` and reparent the previous node.
let id = self.tree.add_node(Node {
parent: Some(self.cur),
..Node::default()
});
self.set_cur_node(id);
self.tree.get_node_mut(cur_id).right = Some(id);
self.cur_node_mut().left = Some(node);
}
None => {
let id = self.add_right_child_cur(Node::default());
self.set_cur_node(id);
}
};
}
self.cur_node_mut().data = Some(*t);
}
fn set_cur_node(&mut self, id: NodeId) {
assert_ne!(Some(self.cur), self.cur_node().parent);
self.cur = id;
}
fn set_cur_to_parent(&mut self) {
match self.cur_node().parent {
Some(parent) => self.set_cur_node(parent),
None => {
let id = self.tree.add_node(Node::default());
self.cur_node_mut().parent = Some(id);
let old_id = self.cur;
self.tree.root = id;
self.set_cur_node(id);
self.cur_node_mut().left = Some(old_id);
}
}
}
fn add_token(&mut self, t: &Token) {
//TODO(wathiede): we seem to be building the tree backwards so that walking the tree works
// right-to-left instead of left-to-right.
self.debug_tokens.push(*t);
match t {
Token::Num(n) => {
self.cur_node_mut().data = Some(*t);
self.cur = self.cur_node_mut().parent;
Token::Num(_) => {
self.set_cur_data(t);
self.set_cur_to_parent();
}
Token::Add => {
self.cur_node_mut().data = Some(*t);
self.set_cur_data(t);
let id = self.add_right_child_cur(Node::default());
self.cur = id;
}
Token::Mul => {
self.cur_node_mut().data = Some(*t);
//dbg!(&self);
self.set_cur_data(t);
let id = self.add_right_child_cur(Node::default());
self.cur = id;
}
@ -188,35 +237,43 @@ impl Parser {
let id = self.add_left_child_cur(Node::default());
self.cur = id;
}
Token::Close => self.cur = self.cur_node_mut().parent,
Token::Close => self.set_cur_to_parent(),
Token::Space => unreachable!("spaces should be filtered"),
};
}
fn eval(&self) -> u32 {
dbg!(&self.debug_tokens);
dbg!(&self.tree);
dbg!(format!("{}", self.tree));
fn eval_inner(tree: &Tree, id: NodeId) -> u32 {
match tree.get_node(id).data {
None => panic!("empty node"),
Some(Token::Num(n)) => n,
Some(Token::Add) => {
eval_inner(tree, tree.get_node(id).left.unwrap())
+ eval_inner(tree, tree.get_node(id).right.unwrap())
let l = eval_inner(tree, tree.get_node(id).left.unwrap());
let r = eval_inner(tree, tree.get_node(id).right.unwrap());
dbg!(l, r);
dbg!(l + r)
}
Some(Token::Mul) => {
eval_inner(tree, tree.get_node(id).left.unwrap())
* eval_inner(tree, tree.get_node(id).right.unwrap())
let l = eval_inner(tree, tree.get_node(id).left.unwrap());
let r = eval_inner(tree, tree.get_node(id).right.unwrap());
dbg!(l, r);
dbg!(l * r)
}
Some(Token::Open) => panic!("("),
Some(Token::Close) => panic!(")"),
Some(Token::Space) => panic!(" "),
}
}
eval_inner(&self.tree, NodeId(0))
eval_inner(&self.tree, self.tree.root)
}
}
#[aoc_generator(day18)]
fn generator(input: &str) -> Vec<Vec<Token>> {
input.split('\n').map(lex).collect()
}
fn lex(input: &str) -> Vec<Token> {
input
.bytes()
@ -236,13 +293,14 @@ fn lex(input: &str) -> Vec<Token> {
fn parse(tokens: &[Token]) -> u32 {
let mut p = Parser::default();
p.parse(tokens);
dbg!(&p);
tokens.into_iter().for_each(|t| p.add_token(t));
p.eval()
}
#[aoc(day18, part1)]
fn solution1(tokens: &[Token]) -> u32 {
parse(tokens)
fn solution1(tokens_list: &[Vec<Token>]) -> u32 {
tokens_list.iter().map(|tokens| parse(tokens)).sum()
}
#[cfg(test)]
@ -268,13 +326,14 @@ mod tests {
#[test]
fn part1() {
for (input, want) in vec![
("(1 + 2 * 3 + 4 * 5 + 6)", 71),
("1 + 2 * 3 + 4 * 5 + 6", 71),
("2 * 3 + (4 * 5)", 26),
("5 + (8 * 3 + 9 + 3 * 4 * 3)", 437),
("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))", 12240),
("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2", 13632),
] {
assert_eq!(solution1(&lex(input)), want, "{}", input);
dbg!(&input);
assert_eq!(parse(&lex(input)), want, "{}", input);
}
}
}