Created
December 11, 2019 15:27
-
-
Save mattmess1221/d10279ab295a89a165c10d29538fb582 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import enum | |
from typing import Dict, Tuple | |
import aoc | |
import bytecode | |
def main(): | |
instrs = load_instructions() | |
w = World(instrs) | |
w.robot.run() | |
print(len(w.grid)) | |
w.render() | |
def load_instructions(): | |
with aoc.open_input(__name__) as f: | |
return [int(i) for i in f.read().split(',')] | |
class Direction(enum.Enum): | |
UP = 0 | |
RIGHT = 1 | |
DOWN = 2 | |
LEFT = 3 | |
def prev(self): | |
return Direction((self.value - 1) % 4) | |
def next(self): | |
return Direction((self.value + 1) % 4) | |
class World: | |
def __init__(self, instructions): | |
self.grid: Dict[Tuple[int, int], int] = {(0, 0): 1} | |
self.robot = Robot(self, instructions) | |
def render(self): | |
min_x = min([x for x, y in self.grid.keys()]) | |
min_y = min([y for x, y in self.grid.keys()]) | |
max_x = max([x for x, y in self.grid.keys()]) | |
max_y = max([y for x, y in self.grid.keys()]) | |
for y in reversed(range(min_y, max_y + 1)): | |
print("{:>3}".format(y), end=' ') | |
for x in range(min_x, max_x + 1): | |
color = self.grid.get((x, y)) | |
if color == 0: | |
c = '.' | |
elif color == 1: | |
c = '#' | |
else: | |
c = '.' | |
print(c, end=' ') | |
print() | |
class Robot: | |
def __init__(self, world: World, instructions): | |
self.world = world | |
self.pos = 0, 0 | |
self.direction = Direction.UP | |
self.state = False | |
self.computer = bytecode.Bytecode(instructions + [0] * 1024) | |
self.computer.stdin.read = self.get_color | |
self.computer.stdout.write = self.handle_output | |
def get_color(self): | |
return self.world.grid.get(self.pos, 0) | |
def handle_output(self, value): | |
if self.state: | |
self.state = False | |
if value: | |
self.direction = self.direction.next() | |
else: | |
self.direction = self.direction.prev() | |
self.move() | |
else: | |
self.state = True | |
self.world.grid[self.pos] = value | |
def run(self): | |
self.computer.start() | |
self.computer.join() | |
def move(self): | |
direction = self.direction | |
def _move(x, y): | |
if direction is Direction.UP: | |
return x, y + 1 | |
if direction is Direction.RIGHT: | |
return x + 1, y | |
if direction is Direction.DOWN: | |
return x, y - 1 | |
if direction is Direction.LEFT: | |
return x - 1, y | |
self.pos = _move(*self.pos) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment