From 5d09932b11b9eb1ae79b68d4fa8a83a3f782ce91 Mon Sep 17 00:00:00 2001 From: dece Date: Tue, 8 Dec 2020 19:45:26 +0100 Subject: [PATCH] Day 8 in Rust --- 2020/day8.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 2020/day8.rs diff --git a/2020/day8.rs b/2020/day8.rs new file mode 100644 index 0000000..b32b015 --- /dev/null +++ b/2020/day8.rs @@ -0,0 +1,78 @@ +use std::collections; +use std::fs; +use std::io::{self, BufRead}; + +#[derive(Clone)] +enum Op { + Nop(i64), + Jmp(i64), + Acc(i64), +} + +struct Cpu { + ip: u64, + acc: i64, +} + +impl Cpu { + fn step(&mut self, code: &Vec) { + match code[self.ip as usize] { + Op::Nop(_) => {}, + Op::Jmp(i) => { self.ip = (self.ip as i64 + i) as u64; return } + Op::Acc(i) => { self.acc += i } + } + self.ip += 1; + } +} + +fn main() { + let file = fs::File::open("day8.txt").unwrap(); + let lines: Vec = io::BufReader::new(file).lines().map(|r| r.unwrap()).collect(); + let mut code: Vec = lines.iter().map(|line| { + let inst: Vec<&str> = line.splitn(2, " ").collect(); + match inst[0] { + "nop" => Op::Nop(inst[1].parse::().unwrap()), + "jmp" => Op::Jmp(inst[1].parse::().unwrap()), + "acc" => Op::Acc(inst[1].parse::().unwrap()), + unk => panic!("Unknown op '{}'", unk), + } + }).collect(); + + // Part 1. + let mut visited: collections::HashSet = collections::HashSet::new(); + let mut cpu = Cpu { ip: 0, acc: 0 }; + while !visited.contains(&cpu.ip) { + visited.insert(cpu.ip); + cpu.step(&code); + } + println!("Acc after first revisit: {}.", cpu.acc); + + // Part 2. + for i in 0..code.len() { + match &code[i] { + Op::Jmp(val) => { + let op_backup = code[i].clone(); + code[i] = Op::Nop(*val); + if let Some(acc) = run(&code) { + println!("Acc after non-looping execution: {}.", acc); + break + } + code[i] = op_backup; + } + _ => {} + } + } +} + +fn run(code: &Vec) -> Option { + let mut visited: collections::HashSet = collections::HashSet::new(); + let mut cpu = Cpu { ip: 0, acc: 0 }; + while cpu.ip < code.len() as u64 { + visited.insert(cpu.ip); + cpu.step(&code); + if visited.contains(&cpu.ip) { + return None + } + } + Some(cpu.acc) +}