21.py
1 from lib import * 2 3 input = read_input(2019, 21) 4 5 6 class IntCode: 7 def __init__(self, mem): 8 self.mem = {i: e for i, e in enumerate(mem)} 9 self.pc = 0 10 self.running = False 11 self.inp = [] 12 self.out = [] 13 self.rel = 0 14 15 def start(self): 16 self.running = True 17 self.cont() 18 19 def get_arg(self, i): 20 mode = self.mem[self.pc] // (10 ** (i + 1)) % 10 21 out = self.mem[self.pc + i] 22 if mode == 1: 23 return out 24 elif mode == 2: 25 out += self.rel 26 return self.mem.get(out, 0) 27 28 def write_arg(self, i, value): 29 mode = self.mem[self.pc] // (10 ** (i + 1)) % 10 30 pos = self.mem[self.pc + i] 31 assert mode != 1 32 if mode == 2: 33 pos += self.rel 34 self.mem[pos] = value 35 36 def cont(self): 37 while True: 38 opcode = self.mem[self.pc] % 100 39 40 if opcode == 1: 41 self.write_arg(3, self.get_arg(1) + self.get_arg(2)) 42 self.pc += 4 43 elif opcode == 2: 44 self.write_arg(3, self.get_arg(1) * self.get_arg(2)) 45 self.pc += 4 46 elif opcode == 3: 47 if not self.inp: 48 return 49 self.write_arg(1, self.inp.pop(0)) 50 self.pc += 2 51 elif opcode == 4: 52 self.out.append(self.get_arg(1)) 53 self.pc += 2 54 elif opcode == 5: 55 if self.get_arg(1): 56 self.pc = self.get_arg(2) 57 else: 58 self.pc += 3 59 elif opcode == 6: 60 if not self.get_arg(1): 61 self.pc = self.get_arg(2) 62 else: 63 self.pc += 3 64 elif opcode == 7: 65 self.write_arg(3, int(self.get_arg(1) < self.get_arg(2))) 66 self.pc += 4 67 elif opcode == 8: 68 self.write_arg(3, int(self.get_arg(1) == self.get_arg(2))) 69 self.pc += 4 70 elif opcode == 9: 71 self.rel += self.get_arg(1) 72 self.pc += 2 73 elif opcode == 99: 74 self.running = False 75 return 76 77 78 (*mem,) = map(int, input.split(",")) 79 intcode = IntCode(mem) 80 intcode.start() 81 intcode.out.clear() 82 INSTRUCTIONS = ["NOT A J", "NOT B T", "OR T J", "NOT C T", "OR T J", "AND D J", "WALK"] 83 intcode.inp += map(ord, "".join(i + "\n" for i in INSTRUCTIONS)) 84 intcode.cont() 85 print(intcode.out[-1]) 86 87 88 (*mem,) = map(int, input.split(",")) 89 intcode = IntCode(mem) 90 intcode.start() 91 intcode.out.clear() 92 INSTRUCTIONS = [ 93 "NOT A J", 94 "NOT B T", 95 "OR T J", 96 "NOT C T", 97 "OR T J", 98 "AND D J", 99 "NOT I T", 100 "NOT T T", 101 "OR F T", 102 "AND E T", 103 "OR H T", 104 "AND T J", 105 "RUN", 106 ] 107 intcode.inp += map(ord, "".join(i + "\n" for i in INSTRUCTIONS)) 108 intcode.cont() 109 print(intcode.out[-1])