2020: day08: part 2
This commit is contained in:
parent
bdef7fcbe4
commit
09a9654a1b
|
@ -9,6 +9,7 @@ pub fn run() -> aoc::Result<String> {
|
||||||
let mut res = String::with_capacity(128);
|
let mut res = String::with_capacity(128);
|
||||||
|
|
||||||
writeln!(res, "part 1: {}", part1(INPUT)?)?;
|
writeln!(res, "part 1: {}", part1(INPUT)?)?;
|
||||||
|
writeln!(res, "part 2: {}", part2(INPUT)?)?;
|
||||||
|
|
||||||
Ok(res)
|
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 {
|
struct Interpreter {
|
||||||
idx: usize,
|
idx: usize,
|
||||||
accumulator: i64,
|
accumulator: i64,
|
||||||
|
@ -54,7 +83,7 @@ impl Interpreter {
|
||||||
self.idx += 1;
|
self.idx += 1;
|
||||||
}
|
}
|
||||||
Instruction::Jmp(offset) => self.idx = self.idx.wrapping_add(offset as usize),
|
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();
|
self.step();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ExitStatus::End(self.accumulator);
|
ExitStatus::End(self.accumulator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
enum Instruction {
|
enum Instruction {
|
||||||
Acc(i64),
|
Acc(i64),
|
||||||
Jmp(i64),
|
Jmp(i64),
|
||||||
Nop,
|
Nop(i64),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::str::FromStr for Instruction {
|
impl std::str::FromStr for Instruction {
|
||||||
|
@ -93,7 +123,7 @@ impl std::str::FromStr for Instruction {
|
||||||
Ok(match inst {
|
Ok(match inst {
|
||||||
"acc" => Self::Acc(arg),
|
"acc" => Self::Acc(arg),
|
||||||
"jmp" => Self::Jmp(arg),
|
"jmp" => Self::Jmp(arg),
|
||||||
"nop" => Self::Nop,
|
"nop" => Self::Nop(arg),
|
||||||
_ => return Err(err!("unrecognized instruction `{}`", inst)),
|
_ => return Err(err!("unrecognized instruction `{}`", inst)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -114,4 +144,14 @@ mod tests {
|
||||||
fn part1_real() {
|
fn part1_real() {
|
||||||
assert_eq!(part1(INPUT).unwrap(), 1675);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue