def walk(steps): loc = Point(0, 0) direc = Vector(0, 1, 0) for turn, dist in moves(steps): if turn == 'R': direc = -Vector.k().cross(direc) else: direc = direc.cross(-Vector.k()) loc += dist * direc return loc
def walk_scaffold(layout, robot): direcs = { '>': Vector(1, 0, 0), '<': Vector(-1, 0, 0), '^': Vector(0, -1, 0), 'V': Vector(0, 1, 0) } scaffold = '#' cur_loc = Point(*robot[:2]) cur_dir = direcs[robot[-1]] cur_run = 0 moves = [] while True: #print(cur_loc, cur_dir) next_loc = cur_loc + cur_dir if valid_index( layout, next_loc) and layout[next_loc.y][next_loc.x] == scaffold: cur_loc = next_loc cur_run += 1 else: if cur_run: moves.append(cur_run) cur_run = 0 # All of the directions are kinda flipped from expected because we're in a coordinate system # where +y is down. if cur_dir.x == 1: left = cur_loc.down right = cur_loc.up elif cur_dir.x == -1: left = cur_loc.up right = cur_loc.down elif cur_dir.y == 1: left = cur_loc.right right = cur_loc.left elif cur_dir.y == -1: left = cur_loc.left right = cur_loc.right if valid_index(layout, left) and layout[left.y][left.x] == scaffold: moves.append('L') cur_dir = cur_dir.cross(Vector.k()) elif valid_index(layout, right) and layout[right.y][right.x] == scaffold: moves.append('R') cur_dir = Vector.k().cross(cur_dir) else: break return ','.join(str(i) for i in moves)
def walk2(steps): loc = Point(0, 0) visited = {loc} direc = Vector(0, 1, 0) for turn, dist in cycle(moves(steps)): if turn == 'R': direc = -Vector.k().cross(direc) else: direc = direc.cross(-Vector.k()) for _ in range(dist): loc += direc if loc in visited: return loc else: visited.add(loc)
def paint(codes, start=0): c = Computer(codes) loc = Point(0, 0) direc = Vector(0, 1, 0) panels = {loc: start} while c.running: c.run([panels.get(loc, 0)]) turn = c.output.pop() color = c.output.pop() panels[loc] = color if turn == 0: # Turn left direc = Vector.k().cross(direc) elif turn == 1: # Turn right direc = direc.cross(Vector.k()) loc += direc return panels