Advertisement
Guest User

Untitled

a guest
Dec 11th, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.00 KB | None | 0 0
  1. from collections import defaultdict
  2. from PIL import Image
  3. from subprocess import call
  4.  
  5.  
  6. def animation(count, size_x, size_y, grid):
  7.  
  8.     area_snapshot = grid
  9.  
  10.     tempImage = Image.new("RGB", (size_x, size_y), "black")
  11.     for y in range(size_y):
  12.         for x in range(size_x):
  13.             if area_snapshot[(x, y)] == " ":
  14.                 color = (0, 0, 0)
  15.             elif area_snapshot[(x, y)] == "█":
  16.                 color = (255, 255, 255)
  17.             elif area_snapshot[(x, y)] == "O":
  18.                 color = (0, 255, 0)
  19.             try:
  20.                 tempImage.putpixel((x, y), color)
  21.             except:
  22.                 pass
  23.     tempImage = tempImage.resize((30 * size_x, 30 * size_y))
  24.     tempImage.save(f"output_{count}.png", quality=100)
  25.  
  26.  
  27. class IntcodeComputer(object):
  28.     """Intcode computer class
  29.    """
  30.     def __init__(self, name, program, start_color):
  31.         self.ip = 0
  32.         self.rb = 0
  33.         self.name = name
  34.         self.data = defaultdict(int)
  35.         for i, datum in enumerate(program.copy()):
  36.             self.data[i] = datum
  37.         self.output = []
  38.         self.mode_r = {0: lambda x: self.data[self.data[self.ip + x]],
  39.                        1: lambda x: self.data[self.ip + x],
  40.                        2: lambda x: self.data[self.data[self.ip + x] + self.rb]}
  41.         self.mode_w = {0: lambda x: self.data[self.ip + x],
  42.                        2: lambda x: self.data[self.ip + x] + self.rb}
  43.         self.panel = defaultdict(lambda: " ")
  44.         self.panel[(0, 0)] = start_color
  45.         self.position = (0, 0)
  46.         self.direction = 0
  47.         self.paint_map = {" ": 0, "█": 1}
  48.         self.inv_paint_map = {0: " ", 1: "█"}
  49.         self.turn_map = {0: -90, 1: 90}
  50.         self.direction_map = {0: (0, -1), 90: (1, 0), 180: (0, 1), 270: (-1, 0)}
  51.         self.counter = 0
  52.  
  53.     def execute(self):
  54.         while True:
  55.             if len(self.output) == 2:
  56.                 self.panel[self.position] = self.inv_paint_map[self.output.pop(0)]
  57.  
  58.                 animation(self.counter, 43, 6, self.panel.copy())
  59.                 self.counter += 1
  60.  
  61.                 self.direction = (self.direction + self.turn_map[self.output.pop(0)]) % 360
  62.                 new_x = self.position[0] + self.direction_map[self.direction][0]
  63.                 new_y = self.position[1] + self.direction_map[self.direction][1]
  64.                 self.position = (new_x, new_y)
  65.  
  66.                 t = self.panel[self.position]
  67.                 self.panel[self.position] = "O"
  68.                 animation(self.counter, 43, 6, self.panel)
  69.                 self.counter += 1
  70.                 self.panel[self.position] = t
  71.  
  72.             opcode = str(self.data[self.ip]).zfill(5)
  73.             mode_A, mode_B, mode_C, opcode = int(opcode[2]), int(opcode[1]), int(opcode[0]), int(opcode[3:])
  74.  
  75.             if opcode == 99:
  76.                 animation(self.counter, 43, 6, self.panel)
  77.                 return self.panel
  78.             if opcode in [1, 2]:
  79.                 param_A, param_B, param_C = self.mode_r[mode_A](1), self.mode_r[mode_B](2), self.mode_w[mode_C](3)
  80.                 if opcode == 1:
  81.                     self.data[param_C] = param_A + param_B
  82.                 else:
  83.                     self.data[param_C] = param_A * param_B
  84.                 self.ip += 4
  85.             if opcode in [3, 4]:
  86.                 if opcode == 3:
  87.                     param_A = self.mode_w[mode_A](1)
  88.                     self.data[param_A] = self.paint_map[self.panel[self.position]]
  89.                 else:
  90.                     param_A = self.mode_r[mode_A](1)
  91.                     self.output.append(param_A)
  92.                 self.ip += 2
  93.             if opcode in [5, 6]:
  94.                 param_A, param_B = self.mode_r[mode_A](1), self.mode_r[mode_B](2)
  95.                 if opcode == 5 and param_A or opcode == 6 and not param_A:
  96.                     self.ip = param_B
  97.                 else:
  98.                     self.ip += 3
  99.             if opcode in [7, 8]:
  100.                 param_A, param_B, param_C = self.mode_r[mode_A](1), self.mode_r[mode_B](2), self.mode_w[mode_C](3)
  101.                 if opcode == 7:
  102.                     self.data[param_C] = 1 if param_A < param_B else 0
  103.                 else:
  104.                     self.data[param_C] = 1 if param_A == param_B else 0
  105.                 self.ip += 4
  106.             if opcode == 9:
  107.                 param_A = self.mode_r[mode_A](1)
  108.                 self.rb += param_A
  109.                 self.ip += 2
  110.  
  111.  
  112. def main():
  113.     data = [int(char) for char in open('input', 'rt').read().strip().split(",")]
  114.  
  115.     ehpr = IntcodeComputer("EHPR", data, "█")
  116.     panel = ehpr.execute()
  117.  
  118.     x_max = max(panel, key=lambda x: x[0])[0]
  119.     y_max = max(panel, key=lambda x: x[1])[1]
  120.  
  121.     for y in range(y_max + 1):
  122.         for x in range(x_max + 1):
  123.             print(panel[(x, y)], end="")
  124.         print()
  125.  
  126.     call(f"ffmpeg -framerate 30 -f image2 -i output_%d.png -c:v libvpx -b:v 2000k output.webm -y 2>NUL", shell=True)
  127.     call(f"del output_*.png 2>NUL", shell=True)
  128.     return 0
  129.  
  130.  
  131. exit(main())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement