50 lines
1.4 KiB
Rust
50 lines
1.4 KiB
Rust
|
use std::fs;
|
||
|
|
||
|
mod emulator;
|
||
|
|
||
|
use emulator::{parse_code, Emulator, EmulatorError, Instruction};
|
||
|
|
||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||
|
let input = fs::read_to_string("input")?;
|
||
|
let program = parse_code(&input)?;
|
||
|
|
||
|
// Part 1
|
||
|
let mut emulator = Emulator::new();
|
||
|
if let Err(EmulatorError::InfiniteLoop { accumulator }) =
|
||
|
emulator.run_program_finitely(&program)
|
||
|
{
|
||
|
println!("{}", accumulator);
|
||
|
} else {
|
||
|
panic!("We should get an infinite loop.");
|
||
|
}
|
||
|
|
||
|
// Part 2
|
||
|
let result = program
|
||
|
.iter()
|
||
|
.enumerate()
|
||
|
.filter_map(|(i, instruction)| match instruction {
|
||
|
(Instruction::Jump, arg) => {
|
||
|
let mut program = program.clone();
|
||
|
program[i] = (Instruction::NoOperation, *arg);
|
||
|
emulator.reset();
|
||
|
emulator.run_program_finitely(&program).ok()
|
||
|
}
|
||
|
(Instruction::NoOperation, arg) => {
|
||
|
let mut program = program.clone();
|
||
|
program[i] = (Instruction::Jump, *arg);
|
||
|
emulator.reset();
|
||
|
emulator.run_program_finitely(&program).ok()
|
||
|
}
|
||
|
(_, _) => None,
|
||
|
})
|
||
|
.next();
|
||
|
|
||
|
if let Some(result) = result {
|
||
|
println!("{}", result);
|
||
|
} else {
|
||
|
panic!("We should have at least one non-infinte loop.");
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|