day 8 part 1 solution

Signed-off-by: Stephen Waits <swaits@amazon.com>
This commit is contained in:
Stephen Waits committed 2020-12-09 21:14:03 -08:00
1 parent acd90a85ac
commit 7caf5dc27a
4 files changed
+791

No files matched your search

+133
View File
@@ -0,0 +1,133 @@
// ==== day 8
use crate::utils;
use anyhow::{anyhow, Result};
use std::str::FromStr;
#[derive(Debug)]
enum Instruction {
Acc(i32),
Jmp(i32),
Nop(i32),
}
impl FromStr for Instruction {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parsed: Vec<&str> = s.trim().split(' ').collect();
if parsed.len() != 2 {
return Err(anyhow!("instruction parse error"));
}
let opcode = parsed[0];
let operand = parsed[1].parse::<i32>()?;
match opcode {
"acc" => Ok(Instruction::Acc(operand)),
"jmp" => Ok(Instruction::Jmp(operand)),
"nop" => Ok(Instruction::Nop(operand)),
_ => Err(anyhow!("unknown instruction")),
}
}
}
#[derive(Debug, Default)]
struct Console {
pc: usize, // program counter
hits: Vec<usize>, // instruction hits
accumulator: i32, // accumulator (starts at 0)
program: Vec<Instruction>, // program is just an array of instructions
}
impl FromStr for Console {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let memory: Vec<Instruction> = s
.lines()
.map(|l| Instruction::from_str(l).unwrap())
.collect();
Ok(Console {
pc: 0,
hits: vec![0; memory.len()],
accumulator: 0,
program: memory,
})
}
}
#[derive(PartialEq)]
enum Status {
Running,
Completed,
Halted,
}
impl Console {
fn reset(&mut self) {
self.pc = 0;
self.accumulator = 0;
self.hits = vec![0; self.program.len()];
}
fn get_run_state(&self) -> Status {
// check pc
if !(0..self.program.len()).contains(&self.pc) {
Status::Completed
}
// guard against infinite loops
else if self.hits[self.pc] > 0 {
Status::Halted
} else {
Status::Running
}
}
fn step(&mut self) -> Status {
// verify we're running
if self.get_run_state() != Status::Running {
return self.get_run_state();
}
// execute instruction at pc
self.hits[self.pc] += 1;
match self.program[self.pc] {
Instruction::Acc(n) => {
self.accumulator += n;
self.pc += 1;
}
Instruction::Jmp(n) => {
if n < 0 {
self.pc -= n.abs() as usize;
} else {
self.pc += n as usize;
}
}
Instruction::Nop(_) => {
self.pc += 1;
}
}
Status::Running
}
fn run(&mut self) -> i32 {
self.reset();
while self.step() == Status::Running {}
self.accumulator
}
}
pub fn run() -> Result<(i32, i32)> {
let data = utils::read_file("data/input-08.txt")?;
let answers = utils::read_i64s("data/output-08.txt")?;
let mut console = Console::from_str(&data)?;
println!("{:?}", console);
let p1 = console.run();
let p2 = 0;
assert_eq!(p1, answers[0] as i32);
assert_eq!(p2, answers[1] as i32);
Ok((p1, p2))
}
+2
View File
@@ -7,6 +7,7 @@ mod day04;
mod day05;
mod day06;
mod day07;
mod day08;
mod utils;
// TODO
@@ -27,5 +28,6 @@ fn main() -> Result<()> {
println!("Day 05: {:?}", day05::run()?);
println!("Day 06: {:?}", day06::run()?);
println!("Day 07: {:?}", day07::run()?);
println!("Day 08: {:?}", day08::run()?);
Ok(())
}