2020: day08: part 2

This commit is contained in:
Antoine Martin 2020-12-08 16:50:43 +01:00
parent bdef7fcbe4
commit 09a9654a1b

View file

@ -9,6 +9,7 @@ pub fn run() -> aoc::Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
@ -27,6 +28,34 @@ fn part1(input: &str) -> aoc::Result<i64> {
})
}
fn part2(input: &str) -> aoc::Result<i64> {
let instructions = input
.lines()
.map(|line| line.parse())
.collect::<aoc::Result<Vec<Instruction>>>()?;
for idx in 0..instructions.len() {
let mut instructions = instructions.clone();
match instructions[idx] {
Instruction::Acc(_) => continue,
Instruction::Jmp(offset) => instructions[idx] = Instruction::Nop(offset),
Instruction::Nop(offset) => instructions[idx] = Instruction::Jmp(offset),
};
let mut interpreter = Interpreter::new(instructions);
match interpreter.run() {
ExitStatus::InfiniteLoop(_) => continue,
ExitStatus::End(value) => return Ok(value),
}
}
Err(err!(
"interpreter always had an infinite loop, no solution found"
))
}
struct Interpreter {
idx: usize,
accumulator: i64,
@ -54,7 +83,7 @@ impl Interpreter {
self.idx += 1;
}
Instruction::Jmp(offset) => self.idx = self.idx.wrapping_add(offset as usize),
Instruction::Nop => self.idx += 1,
Instruction::Nop(_) => self.idx += 1,
}
}
@ -69,14 +98,15 @@ impl Interpreter {
self.step();
}
return ExitStatus::End(self.accumulator);
ExitStatus::End(self.accumulator)
}
}
#[derive(Clone)]
enum Instruction {
Acc(i64),
Jmp(i64),
Nop,
Nop(i64),
}
impl std::str::FromStr for Instruction {
@ -93,7 +123,7 @@ impl std::str::FromStr for Instruction {
Ok(match inst {
"acc" => Self::Acc(arg),
"jmp" => Self::Jmp(arg),
"nop" => Self::Nop,
"nop" => Self::Nop(arg),
_ => return Err(err!("unrecognized instruction `{}`", inst)),
})
}
@ -114,4 +144,14 @@ mod tests {
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 1675);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 8);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 1532);
}
}