mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-12-18 10:19:55 +00:00
Add day 8 part 2 solution
This commit is contained in:
parent
37bef8869f
commit
e608483ef0
2 changed files with 109 additions and 58 deletions
|
@ -22,3 +22,6 @@ You might also encounter <= (less than or equal to) or != (not equal to). Howeve
|
|||
|
||||
What is the largest value in any register after completing the instructions in your puzzle input?
|
||||
|
||||
--- Part Two ---
|
||||
|
||||
To be safe, the CPU also needs to know the highest value held in any register during this process so that it can decide how much memory to allocate to these operations. For example, in the above instructions, the highest value ever held was 10 (in register c after the third instruction was evaluated).
|
||||
|
|
|
@ -3,18 +3,32 @@ use std::fs::File;
|
|||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
type Registers = HashMap<String, i64>;
|
||||
|
||||
fn main() {
|
||||
let mut input = String::new();
|
||||
let mut file = File::open("input").expect("unable to open input file");
|
||||
file.read_to_string(&mut input).expect("error reading input");
|
||||
|
||||
let max = max_value(&eval(&input));
|
||||
println!("{}", max);
|
||||
pub struct RegisterMachine {
|
||||
registers: HashMap<String, i64>,
|
||||
max_seen: i64
|
||||
}
|
||||
|
||||
fn eval_cond(lhs: i64, cond: &str, rhs: i64) -> bool {
|
||||
impl RegisterMachine {
|
||||
pub fn new() -> Self {
|
||||
RegisterMachine {
|
||||
registers: HashMap::new(),
|
||||
max_seen: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn max(&self) -> i64 {
|
||||
*self.registers.values().max().unwrap()
|
||||
}
|
||||
|
||||
pub fn registers(&self) -> &HashMap<String, i64> {
|
||||
&self.registers
|
||||
}
|
||||
|
||||
pub fn max_seen(&self) -> i64 {
|
||||
self.max_seen
|
||||
}
|
||||
|
||||
fn eval_cond(lhs: i64, cond: &str, rhs: i64) -> bool {
|
||||
match cond {
|
||||
"==" => lhs == rhs,
|
||||
"!=" => lhs != rhs,
|
||||
|
@ -24,9 +38,9 @@ fn eval_cond(lhs: i64, cond: &str, rhs: i64) -> bool {
|
|||
"<=" => lhs <= rhs,
|
||||
_ => panic!("unknown cond op, '{}'", cond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_line(registers: &mut Registers, line: &str) {
|
||||
fn eval_line(&mut self, line: &str) {
|
||||
let tokens = line.split_whitespace().collect::<Vec<_>>();
|
||||
|
||||
// b inc 5 if a > 1
|
||||
|
@ -37,32 +51,38 @@ fn eval_line(registers: &mut Registers, line: &str) {
|
|||
let cond_op = tokens[5];
|
||||
let cond_operand = i64::from_str(tokens[6]).expect("cond operand is not a number");
|
||||
|
||||
if eval_cond(registers.get(cond_reg).map(|val| *val).unwrap_or(0), cond_op, cond_operand) {
|
||||
if !registers.contains_key(register) {
|
||||
registers.insert(register.to_owned(), 0);
|
||||
if RegisterMachine::eval_cond(self.registers.get(cond_reg).map(|val| *val).unwrap_or(0), cond_op, cond_operand) {
|
||||
if !self.registers.contains_key(register) {
|
||||
self.registers.insert(register.to_owned(), 0);
|
||||
}
|
||||
|
||||
let register_val = registers.get_mut(register).unwrap();
|
||||
let register_val = self.registers.get_mut(register).unwrap();
|
||||
match op {
|
||||
"inc" => *register_val += op_operand,
|
||||
"dec" => *register_val -= op_operand,
|
||||
_ => panic!("unknown operation, '{}'", op)
|
||||
}
|
||||
self.max_seen = self.max_seen.max(*register_val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn eval(input: &str) -> Registers {
|
||||
let mut registers = HashMap::new();
|
||||
|
||||
fn eval(&mut self, input: &str) {
|
||||
for line in input.lines() {
|
||||
eval_line(&mut registers, line);
|
||||
self.eval_line(line);
|
||||
}
|
||||
}
|
||||
|
||||
registers
|
||||
}
|
||||
|
||||
fn max_value(registers: &Registers) -> i64 {
|
||||
*registers.values().max().unwrap()
|
||||
fn main() {
|
||||
let mut input = String::new();
|
||||
let mut file = File::open("input").expect("unable to open input file");
|
||||
file.read_to_string(&mut input).expect("error reading input");
|
||||
|
||||
let mut machine = RegisterMachine::new();
|
||||
machine.eval(&input);
|
||||
println!("Part 1: {}", machine.max());
|
||||
println!("Part 2: {}", machine.max_seen());
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -76,14 +96,42 @@ fn test_eval() {
|
|||
expected.insert("a".to_owned(), 1);
|
||||
expected.insert("c".to_owned(), -10);
|
||||
|
||||
assert_eq!(eval(input), expected);
|
||||
let mut machine = RegisterMachine::new();
|
||||
machine.eval(input);
|
||||
|
||||
assert_eq!(machine.registers(), &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_max_value() {
|
||||
let mut registers = HashMap::new();
|
||||
registers.insert("a".to_owned(), 1);
|
||||
registers.insert("c".to_owned(), -10);
|
||||
let input = "b inc 5 if a > 1\na inc 1 if b < 5\nc dec -10 if a >= 1\nc inc -20 if c == 10\n";
|
||||
let mut expected = HashMap::new();
|
||||
|
||||
assert_eq!(max_value(®isters), 1);
|
||||
// a is increased by 1 (to 1) because b is less than 5 (it is 0).
|
||||
// c is decreased by -10 (to 10) because a is now greater than or equal to 1 (it is 1).
|
||||
// c is increased by -20 (to -10) because c is equal to 10.
|
||||
expected.insert("a".to_owned(), 1);
|
||||
expected.insert("c".to_owned(), -10);
|
||||
|
||||
let mut machine = RegisterMachine::new();
|
||||
machine.eval(input);
|
||||
|
||||
assert_eq!(machine.max(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_max_seen() {
|
||||
let input = "b inc 5 if a > 1\na inc 1 if b < 5\nc dec -10 if a >= 1\nc inc -20 if c == 10\n";
|
||||
let mut expected = HashMap::new();
|
||||
|
||||
// a is increased by 1 (to 1) because b is less than 5 (it is 0).
|
||||
// c is decreased by -10 (to 10) because a is now greater than or equal to 1 (it is 1).
|
||||
// c is increased by -20 (to -10) because c is equal to 10.
|
||||
expected.insert("a".to_owned(), 1);
|
||||
expected.insert("c".to_owned(), -10);
|
||||
|
||||
let mut machine = RegisterMachine::new();
|
||||
machine.eval(input);
|
||||
|
||||
assert_eq!(machine.max_seen(), 10);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue