2020: day08: part 1
This commit is contained in:
parent
76bd7d9c54
commit
71a100179e
6 changed files with 724 additions and 0 deletions
105
aoc2020/src/day08.rs
Normal file
105
aoc2020/src/day08.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
use std::collections::HashSet;
|
||||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
|
||||
const INPUT: &str = include_str!("../input/day08.txt");
|
||||
|
||||
pub fn run() -> aoc::Result<String> {
|
||||
let mut res = String::with_capacity(128);
|
||||
|
||||
writeln!(res, "part 1: {}", part1(INPUT)?)?;
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> aoc::Result<i64> {
|
||||
let instructions = input
|
||||
.lines()
|
||||
.map(|line| line.parse())
|
||||
.collect::<aoc::Result<Vec<Instruction>>>()?;
|
||||
|
||||
let mut interpreter = Interpreter::new(instructions);
|
||||
|
||||
let mut set = HashSet::new();
|
||||
|
||||
loop {
|
||||
if !set.insert(interpreter.idx) {
|
||||
break;
|
||||
}
|
||||
|
||||
interpreter.step();
|
||||
}
|
||||
|
||||
Ok(interpreter.accumulator)
|
||||
}
|
||||
|
||||
struct Interpreter {
|
||||
idx: usize,
|
||||
accumulator: i64,
|
||||
memory: Vec<Instruction>,
|
||||
}
|
||||
|
||||
impl Interpreter {
|
||||
fn new(instructions: Vec<Instruction>) -> Self {
|
||||
Self {
|
||||
idx: 0,
|
||||
accumulator: 0,
|
||||
memory: instructions,
|
||||
}
|
||||
}
|
||||
|
||||
fn step(&mut self) {
|
||||
match self.memory[self.idx] {
|
||||
Instruction::Acc(arg) => {
|
||||
self.accumulator += arg;
|
||||
self.idx += 1;
|
||||
}
|
||||
Instruction::Jmp(offset) => self.idx = self.idx.wrapping_add(offset as usize),
|
||||
Instruction::Nop => self.idx += 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Instruction {
|
||||
Acc(i64),
|
||||
Jmp(i64),
|
||||
Nop,
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Instruction {
|
||||
type Err = aoc::Error;
|
||||
|
||||
fn from_str(s: &str) -> aoc::Result<Self> {
|
||||
let space = s.find(' ').ok_or_else(|| err!("couldn't split on space"))?;
|
||||
|
||||
let inst = &s[..space];
|
||||
let arg = s[(space + 1)..]
|
||||
.parse()
|
||||
.map_err(|e| err!("couldn't parse argument for instruction: {}", e))?;
|
||||
|
||||
Ok(match inst {
|
||||
"acc" => Self::Acc(arg),
|
||||
"jmp" => Self::Jmp(arg),
|
||||
"nop" => Self::Nop,
|
||||
_ => return Err(err!("unrecognized instruction `{}`", inst)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const PROVIDED: &str = include_str!("../input/day08_provided.txt");
|
||||
|
||||
#[test]
|
||||
fn part1_provided() {
|
||||
assert_eq!(part1(PROVIDED).unwrap(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() {
|
||||
assert_eq!(part1(INPUT).unwrap(), 1675);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,3 +5,4 @@ pub mod day04;
|
|||
pub mod day05;
|
||||
pub mod day06;
|
||||
pub mod day07;
|
||||
pub mod day08;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use aoc2020::day04;
|
|||
use aoc2020::day05;
|
||||
use aoc2020::day06;
|
||||
use aoc2020::day07;
|
||||
use aoc2020::day08;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let days: &[DayFunc] = &[
|
||||
|
|
@ -18,6 +19,7 @@ fn main() -> Result<()> {
|
|||
day05::run,
|
||||
day06::run,
|
||||
day07::run,
|
||||
day08::run,
|
||||
];
|
||||
|
||||
aoc::run(days)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue