mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-11-08 17:22:31 +00:00
Add day 8 solution
This commit is contained in:
parent
bd49344d80
commit
f10ec4db0f
5 changed files with 1123 additions and 0 deletions
4
2017/day/8/Cargo.lock
generated
Normal file
4
2017/day/8/Cargo.lock
generated
Normal file
|
@ -0,0 +1,4 @@
|
|||
[[package]]
|
||||
name = "day8"
|
||||
version = "0.1.0"
|
||||
|
6
2017/day/8/Cargo.toml
Normal file
6
2017/day/8/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day8"
|
||||
version = "0.1.0"
|
||||
authors = ["Wesley Moore <wes@wezm.net>"]
|
||||
|
||||
[dependencies]
|
1000
2017/day/8/input
Normal file
1000
2017/day/8/input
Normal file
File diff suppressed because it is too large
Load diff
24
2017/day/8/problem.txt
Normal file
24
2017/day/8/problem.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--- Day 8: I Heard You Like Registers ---
|
||||
|
||||
You receive a signal directly from the CPU. Because of your recent assistance with jump instructions, it would like you to compute the result of a series of unusual register instructions.
|
||||
|
||||
Each instruction consists of several parts: the register to modify, whether to increase or decrease that register's value, the amount by which to increase or decrease it, and a condition. If the condition fails, skip the instruction without modifying the register. The registers all start at 0. The instructions look like this:
|
||||
|
||||
b inc 5 if a > 1
|
||||
a inc 1 if b < 5
|
||||
c dec -10 if a >= 1
|
||||
c inc -20 if c == 10
|
||||
|
||||
These instructions would be processed as follows:
|
||||
|
||||
Because a starts at 0, it is not greater than 1, and so b is not modified.
|
||||
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.
|
||||
|
||||
After this process, the largest value in any register is 1.
|
||||
|
||||
You might also encounter <= (less than or equal to) or != (not equal to). However, the CPU doesn't have the bandwidth to tell you what all the registers are named, and leaves that to you to determine.
|
||||
|
||||
What is the largest value in any register after completing the instructions in your puzzle input?
|
||||
|
89
2017/day/8/src/main.rs
Normal file
89
2017/day/8/src/main.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use std::io::Read;
|
||||
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);
|
||||
}
|
||||
|
||||
fn eval_cond(lhs: i64, cond: &str, rhs: i64) -> bool {
|
||||
match cond {
|
||||
"==" => lhs == rhs,
|
||||
"!=" => lhs != rhs,
|
||||
">" => lhs > rhs,
|
||||
">=" => lhs >= rhs,
|
||||
"<" => lhs < rhs,
|
||||
"<=" => lhs <= rhs,
|
||||
_ => panic!("unknown cond op, '{}'", cond)
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_line(registers: &mut Registers, line: &str) {
|
||||
let tokens = line.split_whitespace().collect::<Vec<_>>();
|
||||
|
||||
// b inc 5 if a > 1
|
||||
let register = tokens[0];
|
||||
let op = tokens[1];
|
||||
let op_operand = i64::from_str(tokens[2]).expect("op operand is not a number");
|
||||
let cond_reg = tokens[4];
|
||||
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);
|
||||
}
|
||||
|
||||
let register_val = registers.get_mut(register).unwrap();
|
||||
match op {
|
||||
"inc" => *register_val += op_operand,
|
||||
"dec" => *register_val -= op_operand,
|
||||
_ => panic!("unknown operation, '{}'", op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn eval(input: &str) -> Registers {
|
||||
let mut registers = HashMap::new();
|
||||
|
||||
for line in input.lines() {
|
||||
eval_line(&mut registers, line);
|
||||
}
|
||||
|
||||
registers
|
||||
}
|
||||
|
||||
fn max_value(registers: &Registers) -> i64 {
|
||||
*registers.values().max().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eval() {
|
||||
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);
|
||||
|
||||
assert_eq!(eval(input), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_max_value() {
|
||||
let mut registers = HashMap::new();
|
||||
registers.insert("a".to_owned(), 1);
|
||||
registers.insert("c".to_owned(), -10);
|
||||
|
||||
assert_eq!(max_value(®isters), 1);
|
||||
}
|
Loading…
Reference in a new issue