/ Python / 2019 / 13.py
13.py
  1  from lib import *
  2  
  3  input = read_input(2019, 13)
  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  blocks = 0
 82  while intcode.out:
 83      _, _, t = intcode.out[:3]
 84      del intcode.out[:3]
 85      blocks += t == 2
 86  print(blocks)
 87  
 88  
 89  (*mem,) = map(int, input.split(","))
 90  mem[0] = 2
 91  intcode = IntCode(mem)
 92  intcode.start()
 93  ball = None
 94  paddle = None
 95  score = 0
 96  while intcode.out:
 97      x, _, t = intcode.out[:3]
 98      del intcode.out[:3]
 99      if t == 3:
100          paddle = x
101      elif t == 4:
102          ball = x
103  
104  while intcode.running:
105      if paddle < ball:
106          intcode.inp.append(1)
107      elif ball < paddle:
108          intcode.inp.append(-1)
109      else:
110          intcode.inp.append(0)
111      intcode.cont()
112  
113      while intcode.out:
114          x, _, t = intcode.out[:3]
115          del intcode.out[:3]
116          if x == -1:
117              score = t
118          elif t == 3:
119              paddle = x
120          elif t == 4:
121              ball = x
122  print(score)