/ Python / 2019 / 21.py
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])