Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from collections import defaultdict
- from PIL import Image
- from subprocess import call
- def animation(count, size_x, size_y, grid):
- area_snapshot = grid
- tempImage = Image.new("RGB", (size_x, size_y), "black")
- for y in range(size_y):
- for x in range(size_x):
- if area_snapshot[(x, y)] == " ":
- color = (0, 0, 0)
- elif area_snapshot[(x, y)] == "█":
- color = (255, 255, 255)
- elif area_snapshot[(x, y)] == "O":
- color = (0, 255, 0)
- try:
- tempImage.putpixel((x, y), color)
- except:
- pass
- tempImage = tempImage.resize((30 * size_x, 30 * size_y))
- tempImage.save(f"output_{count}.png", quality=100)
- class IntcodeComputer(object):
- """Intcode computer class
- """
- def __init__(self, name, program, start_color):
- self.ip = 0
- self.rb = 0
- self.name = name
- self.data = defaultdict(int)
- for i, datum in enumerate(program.copy()):
- self.data[i] = datum
- self.output = []
- self.mode_r = {0: lambda x: self.data[self.data[self.ip + x]],
- 1: lambda x: self.data[self.ip + x],
- 2: lambda x: self.data[self.data[self.ip + x] + self.rb]}
- self.mode_w = {0: lambda x: self.data[self.ip + x],
- 2: lambda x: self.data[self.ip + x] + self.rb}
- self.panel = defaultdict(lambda: " ")
- self.panel[(0, 0)] = start_color
- self.position = (0, 0)
- self.direction = 0
- self.paint_map = {" ": 0, "█": 1}
- self.inv_paint_map = {0: " ", 1: "█"}
- self.turn_map = {0: -90, 1: 90}
- self.direction_map = {0: (0, -1), 90: (1, 0), 180: (0, 1), 270: (-1, 0)}
- self.counter = 0
- def execute(self):
- while True:
- if len(self.output) == 2:
- self.panel[self.position] = self.inv_paint_map[self.output.pop(0)]
- animation(self.counter, 43, 6, self.panel.copy())
- self.counter += 1
- self.direction = (self.direction + self.turn_map[self.output.pop(0)]) % 360
- new_x = self.position[0] + self.direction_map[self.direction][0]
- new_y = self.position[1] + self.direction_map[self.direction][1]
- self.position = (new_x, new_y)
- t = self.panel[self.position]
- self.panel[self.position] = "O"
- animation(self.counter, 43, 6, self.panel)
- self.counter += 1
- self.panel[self.position] = t
- opcode = str(self.data[self.ip]).zfill(5)
- mode_A, mode_B, mode_C, opcode = int(opcode[2]), int(opcode[1]), int(opcode[0]), int(opcode[3:])
- if opcode == 99:
- animation(self.counter, 43, 6, self.panel)
- return self.panel
- if opcode in [1, 2]:
- param_A, param_B, param_C = self.mode_r[mode_A](1), self.mode_r[mode_B](2), self.mode_w[mode_C](3)
- if opcode == 1:
- self.data[param_C] = param_A + param_B
- else:
- self.data[param_C] = param_A * param_B
- self.ip += 4
- if opcode in [3, 4]:
- if opcode == 3:
- param_A = self.mode_w[mode_A](1)
- self.data[param_A] = self.paint_map[self.panel[self.position]]
- else:
- param_A = self.mode_r[mode_A](1)
- self.output.append(param_A)
- self.ip += 2
- if opcode in [5, 6]:
- param_A, param_B = self.mode_r[mode_A](1), self.mode_r[mode_B](2)
- if opcode == 5 and param_A or opcode == 6 and not param_A:
- self.ip = param_B
- else:
- self.ip += 3
- if opcode in [7, 8]:
- param_A, param_B, param_C = self.mode_r[mode_A](1), self.mode_r[mode_B](2), self.mode_w[mode_C](3)
- if opcode == 7:
- self.data[param_C] = 1 if param_A < param_B else 0
- else:
- self.data[param_C] = 1 if param_A == param_B else 0
- self.ip += 4
- if opcode == 9:
- param_A = self.mode_r[mode_A](1)
- self.rb += param_A
- self.ip += 2
- def main():
- data = [int(char) for char in open('input', 'rt').read().strip().split(",")]
- ehpr = IntcodeComputer("EHPR", data, "█")
- panel = ehpr.execute()
- x_max = max(panel, key=lambda x: x[0])[0]
- y_max = max(panel, key=lambda x: x[1])[1]
- for y in range(y_max + 1):
- for x in range(x_max + 1):
- print(panel[(x, y)], end="")
- print()
- call(f"ffmpeg -framerate 30 -f image2 -i output_%d.png -c:v libvpx -b:v 2000k output.webm -y 2>NUL", shell=True)
- call(f"del output_*.png 2>NUL", shell=True)
- return 0
- exit(main())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement