Advent 2015 Day 7, 8 & 9 Parts 1 & 2
This commit is contained in:
parent
96b06c7bee
commit
de1a181ba5
40 changed files with 1158 additions and 0 deletions
102
advent_of_code_2015/src/day7/part1.rs
Normal file
102
advent_of_code_2015/src/day7/part1.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Value {
|
||||
Literal(u16),
|
||||
Identifier(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Operator {
|
||||
And,
|
||||
Or,
|
||||
RShift,
|
||||
LShift,
|
||||
Not
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Expression {
|
||||
Assign(Value), // 1 token before arrow
|
||||
Binary(Operator, Value, Value), // 3 tokens before arrow
|
||||
Unary(Value), // always not // 2 tokens before arrow
|
||||
}
|
||||
|
||||
fn parse_operator(name: &str) -> Operator {
|
||||
match name {
|
||||
"AND" => Operator::And,
|
||||
"OR" => Operator::Or,
|
||||
"RSHIFT" => Operator::RShift,
|
||||
"LSHIFT" => Operator::LShift,
|
||||
_ => panic!("unexpected operator: {}", name)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_value(value: &str) -> Value {
|
||||
if let Ok(num) = value.parse::<u16>() {
|
||||
Value::Literal(num)
|
||||
} else {
|
||||
Value::Identifier(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_value(value: &Value, expressions: &HashMap<String, Expression>, cache: &mut HashMap<String, u16>) -> u16 {
|
||||
match value {
|
||||
Value::Literal(num) => *num,
|
||||
Value::Identifier(name) => {
|
||||
let result = calculate_wire(name, expressions, cache);
|
||||
cache.insert(name.clone(), result);
|
||||
result
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn calculate_wire(ident: &String, expressions: &HashMap<String, Expression>, cache: &mut HashMap<String, u16>) -> u16 {
|
||||
if let Some(num) = cache.get(ident) {
|
||||
return *num;
|
||||
}
|
||||
|
||||
match expressions.get(ident).unwrap() {
|
||||
Expression::Assign(value) => {
|
||||
solve_value(value, expressions, cache)
|
||||
},
|
||||
Expression::Binary(operator, lhs, rhs) => {
|
||||
match operator {
|
||||
Operator::And => solve_value(lhs, expressions, cache) & solve_value(rhs, expressions, cache),
|
||||
Operator::Or => solve_value(lhs, expressions, cache) | solve_value(rhs, expressions, cache),
|
||||
Operator::RShift => solve_value(lhs, expressions, cache) >> solve_value(rhs, expressions, cache),
|
||||
Operator::LShift => solve_value(lhs, expressions, cache) << solve_value(rhs, expressions, cache),
|
||||
Operator::Not => todo!(),
|
||||
}
|
||||
},
|
||||
Expression::Unary(value) => {
|
||||
!solve_value(value, expressions, cache)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve(input: &str) {
|
||||
let mut value_cache: HashMap<String, u16> = HashMap::new();
|
||||
let expressions = input.lines().map(|line| {
|
||||
let (expr, into) = line.split_once(" -> ").unwrap();
|
||||
let parts = expr.split(" ").collect::<Vec<_>>();
|
||||
|
||||
let parsed = match parts.len() {
|
||||
1 => { // assignment
|
||||
Expression::Assign(parse_value(expr))
|
||||
},
|
||||
2 => {
|
||||
Expression::Unary(parse_value(parts[1]))
|
||||
},
|
||||
3 => {
|
||||
Expression::Binary(parse_operator(parts[1]), parse_value(parts[0]), parse_value(parts[2]))
|
||||
},
|
||||
_ => panic!("unexpected number of parts: {line}")
|
||||
};
|
||||
|
||||
// println!("parsed: {into} -> {parsed:?}");
|
||||
(into.to_string(), parsed)
|
||||
}).collect::<HashMap<_, _>>();
|
||||
|
||||
println!("solve for a: {}", calculate_wire(&"a".into(), &expressions, &mut value_cache));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue