Refactoring with lib

master
Tibor Bizjak 2023-03-21 01:28:20 +01:00
parent 38923eb7a7
commit 1d2a679eb8
3 changed files with 35 additions and 52 deletions

View File

@ -7,8 +7,6 @@ ZERO, ONE, TWO = "012"
BLACK = ZERO BLACK = ZERO
WHITE = ONE WHITE = ONE
encode = {WHITE : Color.WHITE, BLACK : Color.BLACK}
class Image: class Image:
def __init__(self, data, w, h): def __init__(self, data, w, h):
self.data = data self.data = data
@ -30,7 +28,7 @@ class Image:
return '\n'.join(image[i:i+w] for i in range(0, len(image), w)) return '\n'.join(image[i:i+w] for i in range(0, len(image), w))
def __str__(self): def __str__(self):
return repr(self).replace(BLACK, encode[BLACK]).replace(WHITE, encode[WHITE]) return repr(self).replace(BLACK, Color.BLACK).replace(WHITE, Color.WHITE)

View File

@ -1,40 +1,30 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import intcode
from collections import defaultdict from collections import defaultdict
from itertools import cycle from itertools import zip_longest
from functools import partial
import lib
from lib import vector
from intcode import parse, emulator
BLACK = 0 BLACK = 0
WHITE = 1 WHITE = 1
color = {WHITE : u"\u2B1C", decode_color = {
BLACK : u"\u2B1B" WHITE : lib.Color.WHITE,
BLACK : lib.Color.BLACK
} }
UP = (0, 1)
LEFT = 0 LEFT = 0
RIGHT = 1 RIGHT = 1
def rotate(v, dir):
return (-dir) * v[1], dir * v[0]
def left(v):
return rotate(v, 1)
def right(v):
return rotate(v, -1)
def add(v1, v2):
return v1[0] + v2[0], v1[1] + v2[1]
class Canvas(defaultdict): class Canvas(defaultdict):
def __init__(self, color): def __init__(self):
self.color = color super().__init__(int)
super(Canvas, self).__init__(int)
def __str__(self): def __str__(self):
xs, ys = zip(*self.keys()) xs, ys = zip(*self.keys())
return '\n'.join(''.join(self.color[self[(x, y)]] return '\n'.join(''.join(decode_color[self[(x, y)]]
for x in range(min(xs), max(xs)+1)) for x in range(min(xs), max(xs)+1))
for y in range(max(ys), min(ys)-1, -1)) for y in range(max(ys), min(ys)-1, -1))
@ -42,36 +32,31 @@ class Canvas(defaultdict):
return unicode(self).encode("utf-8") return unicode(self).encode("utf-8")
class Robot: def paint(program, canvas):
def __init__(self, program): pos = (0, 0)
self.pos = (0, 0) direction = lib.Cardinals.UP
self.dir = UP
self.comp = intcode.emulator(program) comp = emulator(program)
comp.write_input(pop_input=lambda : canvas[pos])
def paint(self, canvas): zipped = zip_longest(comp, comp, fillvalue=LEFT)
self.comp.write_input(pop_input=lambda : canvas[self.pos]) for color, rotate_dir in zipped:
paint_flags = cycle((True, False)) canvas[pos] = color
rotate = lib.rotate90pos if rotate_dir == LEFT else lib.rotate90neg
for pf, x in zip(paint_flags, self.comp): direction = rotate(direction)
if pf: pos = pos + direction
canvas[self.pos] = x
else:
self.dir = left(self.dir) if x == LEFT else right(self.dir)
self.pos = add(self.pos, self.dir)
def preproc(puzzle_input): def preproc(puzzle_input):
program = intcode.parse(puzzle_input) program = parse(puzzle_input)
paint = lambda c : Robot(program).paint(c) return partial(paint, program)
return paint
def partI(paint): def partI(paint_canvas):
canvas = Canvas(color) canvas = Canvas()
paint(canvas) paint_canvas(canvas)
return len(canvas) return len(canvas)
def partII(paint): def partII(paint_canvas):
canvas = Canvas(color) canvas = Canvas()
canvas[(0, 0)] = WHITE canvas[(0, 0)] = WHITE
paint(canvas) paint_canvas(canvas)
return '\n' + str(canvas) return '\n' + str(canvas)

4
lib.py
View File

@ -76,9 +76,9 @@ def rotate90pos(v):
def rotate90neg(v): def rotate90neg(v):
"""Rotates vector v by 90 degrees in negative direction.""" """Rotates vector v by 90 degrees in negative direction."""
x, y = v x, y = v
return vector((x, -y)) return vector((y, -x))
class Cardinals(Enum): class Cardinals:
UP = vector((0, 1)) UP = vector((0, 1))
DOWN = vector((0, -1)) DOWN = vector((0, -1))
LEFT = vector((-1, 0)) LEFT = vector((-1, 0))