Compare commits
No commits in common. "5d09932b11b9eb1ae79b68d4fa8a83a3f782ce91" and "d5996aed9129a7beac80585e1c755708e8d81fc0" have entirely different histories.
5d09932b11
...
d5996aed91
65
2020/day8.py
65
2020/day8.py
|
@ -1,65 +0,0 @@
|
||||||
def main():
|
|
||||||
with open("day8.txt", "rt") as f:
|
|
||||||
lines = [line.rstrip() for line in f.readlines()]
|
|
||||||
|
|
||||||
# Part 1
|
|
||||||
visited = set()
|
|
||||||
vm = Vm(lines)
|
|
||||||
while vm.ip not in visited:
|
|
||||||
visited.add(vm.ip)
|
|
||||||
vm.step()
|
|
||||||
print("Acc after revisiting op:", vm.acc)
|
|
||||||
|
|
||||||
# Part 2
|
|
||||||
jmps = reversed([i for i, inst in enumerate(vm.code) if inst[0] == "jmp"])
|
|
||||||
for i in jmps:
|
|
||||||
vm.reset()
|
|
||||||
orig_jmp = vm.code[i]
|
|
||||||
vm.code[i] = ["nop", orig_jmp[1]]
|
|
||||||
if not vm.does_loop():
|
|
||||||
print(vm.acc)
|
|
||||||
return
|
|
||||||
# No need to try for nops apparently!
|
|
||||||
|
|
||||||
|
|
||||||
class Vm:
|
|
||||||
|
|
||||||
def __init__(self, code):
|
|
||||||
self.text = code
|
|
||||||
self.reset()
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
self.code = self.parse_code(self.text)
|
|
||||||
self.ip = 0
|
|
||||||
self.acc = 0
|
|
||||||
|
|
||||||
def step(self):
|
|
||||||
inst = self.code[self.ip]
|
|
||||||
if inst[0] == "nop":
|
|
||||||
pass
|
|
||||||
elif inst[0] == "jmp":
|
|
||||||
self.ip += int(inst[1])
|
|
||||||
return
|
|
||||||
elif inst[0] == "acc":
|
|
||||||
self.acc += int(inst[1])
|
|
||||||
self.ip += 1
|
|
||||||
|
|
||||||
def does_loop(self):
|
|
||||||
visited = set()
|
|
||||||
while self.ip < len(self.code):
|
|
||||||
visited.add(self.ip)
|
|
||||||
self.step()
|
|
||||||
if self.ip in visited:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse_code(code):
|
|
||||||
ops = []
|
|
||||||
for line in code:
|
|
||||||
ops.append(line.split())
|
|
||||||
return ops
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
78
2020/day8.rs
78
2020/day8.rs
|
@ -1,78 +0,0 @@
|
||||||
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<Op>) {
|
|
||||||
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<String> = io::BufReader::new(file).lines().map(|r| r.unwrap()).collect();
|
|
||||||
let mut code: Vec<Op> = lines.iter().map(|line| {
|
|
||||||
let inst: Vec<&str> = line.splitn(2, " ").collect();
|
|
||||||
match inst[0] {
|
|
||||||
"nop" => Op::Nop(inst[1].parse::<i64>().unwrap()),
|
|
||||||
"jmp" => Op::Jmp(inst[1].parse::<i64>().unwrap()),
|
|
||||||
"acc" => Op::Acc(inst[1].parse::<i64>().unwrap()),
|
|
||||||
unk => panic!("Unknown op '{}'", unk),
|
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
|
|
||||||
// Part 1.
|
|
||||||
let mut visited: collections::HashSet<u64> = 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<Op>) -> Option<i64> {
|
|
||||||
let mut visited: collections::HashSet<u64> = 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)
|
|
||||||
}
|
|
Loading…
Reference in a new issue