Skip to content

Instantly share code, notes, and snippets.

@killjoy1221
Created December 11, 2019 15:27
Show Gist options
  • Save killjoy1221/d10279ab295a89a165c10d29538fb582 to your computer and use it in GitHub Desktop.
Save killjoy1221/d10279ab295a89a165c10d29538fb582 to your computer and use it in GitHub Desktop.
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