class Arcade(): def __init__(self, screen_size=(40, 20), input_cb=print): self.screen = np.zeros(screen_size) self.vm = ElfMachine(output_cb=self.disp, input_cb=input_cb, mem_size=4096) self.x, self.y = -2, -2 self.score = 0 self.ball = (0, 0) self.paddle = (0, 0) self.frames = [] def run(self, x): self.vm.run_program(x) def disp(self, i): if self.x == -2: self.x = i elif self.y == -2: self.y = i else: x, y, c = self.x, self.y, i self.x, self.y = -2, -2 if x == -1 and y == 0: self.score = c else: self.screen[x, y] = c if c == 4: self.ball = (x, y) elif c == 3: self.paddle = (x, y)
def execute_amps(program, amps): global res, idx, flip res = 0 idx = -1 flip = True def receive(*args, **kwargs): global res res = args[0] def send(*args, **kwargs): global idx, flip if flip: flip = False idx += 1 # print('flip: {}'.format(amps[idx])) if idx > 4: idx = 0 return amps[idx] else: # print('flop: {}'.format(res)) flip = True return res vm = ElfMachine(send, receive) for _ in range(5): vm.run_program(program) return res
def part_one(x): '''Solves part one''' global a, b a = [] b = [] def draw(x): global a, b if x == 10: a.append(b[:]) b = [] else: b.append(x) vm = ElfMachine(output_cb=draw, mem_size=4096) vm.run_program(x) m = np.array(a[:-1]) # print(a) j = find_junctions(m) # plt.figure(1) # plt.imshow(m) # plt.show() ks = 0 for i in j: ks += i[0] * i[1] return ks
def __init__(self, grid=(100,100), pos=None): self.grid = np.full(grid, -1) if pos: self.pos = pos else: self.pos = grid[0]//2,grid[1]//2 self.dist = 0 self.start = self.pos self.dir_db = { 1: [0,1], # North 2: [0,-1],# South 3: [-1,0],# West 4: [1,0] # East } self.dir = 1 self.two_pass = 0 self.G = nx.Graph() self.vm = ElfMachine(input_cb=self.move, output_cb=self.paint, mem_size=4096) # 0: The repair droid hit a wall. Its position has not changed. # 1: The repair droid has moved one step in the requested direction. # 2: The repair droid has moved one step in the requested direction; its new position is the location of the oxygen system. self.status = {}
def execute_amps_feedback(program, amps): global queues from queue import Queue queues = [ Queue(), Queue(), Queue(), Queue(), Queue(), ] queues[0].put(amps[0]) queues[0].put(0) queues[1].put(amps[1]) queues[2].put(amps[2]) queues[3].put(amps[3]) queues[4].put(amps[4]) def rec_wrap(i): def receive(*args, **kwargs): global queues queues[i].put(args[0]) return receive def send_wrap(i): def send(*args, **kwargs): global queues return queues[i].get(block=True) return send vms = [ ElfMachine(input_cb=send_wrap(0), output_cb=rec_wrap(1)), ElfMachine(input_cb=send_wrap(1), output_cb=rec_wrap(2)), ElfMachine(input_cb=send_wrap(2), output_cb=rec_wrap(3)), ElfMachine(input_cb=send_wrap(3), output_cb=rec_wrap(4)), ElfMachine(input_cb=send_wrap(4), output_cb=rec_wrap(0)) ] import threading threads = [] for i in range(5): threads.append( threading.Thread(target=vms[i].run_program, args=(program, ))) for t in threads: t.start() for t in threads: t.join() res = queues[0].get() return res
def __init__(self, screen_size=(40, 20), input_cb=print): self.screen = np.zeros(screen_size) self.vm = ElfMachine(output_cb=self.disp, input_cb=input_cb, mem_size=4096) self.x, self.y = -2, -2 self.score = 0 self.ball = (0, 0) self.paddle = (0, 0) self.frames = []
def part_two(x): '''Solves part two''' rob = HullPaintingRobot() rob.canvas[rob.position[0], rob.position[1]] = 1 vm = ElfMachine(input_cb=rob.observe, output_cb=rob.instruct, mem_size=2048) vm.run_program(x) plt.figure(1) plt.imshow(np.transpose(rob.canvas)) plt.show()
def part_one(x): '''Solves part one''' rob = HullPaintingRobot() vm = ElfMachine(input_cb=rob.observe, output_cb=rob.instruct, mem_size=2048) vm.run_program(x) plt.figure(1) plt.imshow(rob.canvas) plt.show() rob.canvas[rob.canvas == 0] = 1 rob.canvas[rob.canvas == -1] = 0 return np.sum(rob.canvas.flatten())
def part_two(x): '''Solves part two''' global res res = 0 def output_cb(*args, **kwargs): global res print(args, kwargs) res = args[0] def input_cb(*args, **kwargs): return 2 vm = ElfMachine(output_cb=output_cb, input_cb=input_cb, mem_size=2048) vm.run_program(x) return res
def part_one(p): global x, y, grid, vm, flip '''Solves part one''' x, y = -1, 0 flip = True grid = np.zeros((50, 50), dtype=int) def draw(i): global x, y, grid grid[x][y] = i def query(*args, **kwargs): global x, y, vm, flip if flip: flip = False x += 1 if x == 50: y += 1 x = 0 if y == 50: vm.finished = True return x else: flip = True return y vm = ElfMachine(output_cb=draw, input_cb=query, mem_size=4096) for _ in range(50 * 50): vm.run_program(p) plt.figure(1) plt.imshow(grid) plt.show() count = len(np.where(grid.flatten() == 1)[0]) return count
def part_two_visualized(x): '''Visualization''' rob = HullPaintingRobot(canvas_size=50, start=(0, 0)) rob.canvas[rob.position[0], rob.position[1]] = 1 fig, ax = plt.subplots() p = plt.imshow(np.transpose(rob.canvas)) t, = plt.plot([rob.position[0]], [rob.position[1]], rob.sym) frames = [[p, t]] def observe(*args, **kwargs): res = rob.observe(*args, **kwargs) p = plt.imshow(np.transpose(rob.canvas)) t, = plt.plot([rob.position[0]], [rob.position[1]], rob.sym) frames.append([p, t]) return res vm = ElfMachine(input_cb=observe, output_cb=rob.instruct, mem_size=2048) vm.run_program(x) ani = animation.ArtistAnimation(fig, frames, interval=50, blit=False) ani.save('day_11.gif', writer='imagemagick') plt.show()
def test(): '''Test functions''' global res prog = [ 109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99 ] res = [] def output_cb_1(*args, **kwargs): res.append(args[0]) vm = ElfMachine(output_cb=output_cb_1) vm.run_program(prog) assert (prog == res) prog = [1102, 34915192, 34915192, 7, 4, 7, 99, 0] res = 0 def output_cb_2(*args, **kwargs): global res res = args[0] vm = ElfMachine(output_cb=output_cb_2) vm.run_program(prog) assert (len(str(res)) == 16) prog = [104, 1125899906842624, 99] vm = ElfMachine(output_cb=output_cb_2) vm.run_program(prog) assert (res == 1125899906842624)
def part_two(p): '''Solves part two''' global x, y, grid, vm, query_g, xx, yy, fin fin = False grid = {} def draw(i): global x, y, grid, xx, yy grid[(xx, yy)] = i # def query_generator(*args, **kwargs): # global x,y,grid,vm,xx,yy # x,y = 0,0 # xx,yy = 0,0 # while True: # yield x # yield y # if grid[(x,y)] == 0: # y += 1 # yy = y # continue # elif grid[(x,y)] == 1: # yield x # yy = y + 99 # yield y + 99 # if x % 10 == 0: # print('At x =',x) # if grid[(x,y+99)] == 0: # x += 1 # xx = x # y = 0 # yy = y # continue # elif grid[(x,y+99)] == 1: # print('Almost at',x,y) # xx = x+99 # yy = y # yield xx # yield yy # if grid[(xx,yy)] == 1: # print('Found at',x,y) # vm.finished = True # fin = True # else: # x += 1 # xx = x # y = 0 # yy = y def query_generator(*args, **kwargs): global x, y, grid, vm, xx, yy, fin x, y = 0, 10 xx, yy = 0, 10 last_x = 0 S = 99 while True: yield x yield y if grid[(x, y)] == 0: x += 1 xx = x continue elif grid[(x, y)] == 1: xx = x + S last_x = x yield xx yield y # if y % 10 == 0: # print('At y =',y) if grid[(x + S, y)] == 0: y += 1 yy = y x = last_x xx = x continue elif grid[(x + S, y)] == 1: # print('Almost at',x,y) xx = x yy = y + S yield x yield y + S if grid[(x, y + S)] == 1: print('Found at', x, y) vm.finished = True fin = True else: y += 1 yy = y x = last_x xx = x query_g = query_generator() def query(*args, **kwargs): global query_g return next(query_g) vm = ElfMachine(output_cb=draw, input_cb=query, mem_size=8196) while not fin: vm.run_program(p) # plt.figure(1) # plt.imshow(grid) # plt.show() return x * 10000 + y
class RepairDroid(): def __init__(self, grid=(100,100), pos=None): self.grid = np.full(grid, -1) if pos: self.pos = pos else: self.pos = grid[0]//2,grid[1]//2 self.dist = 0 self.start = self.pos self.dir_db = { 1: [0,1], # North 2: [0,-1],# South 3: [-1,0],# West 4: [1,0] # East } self.dir = 1 self.two_pass = 0 self.G = nx.Graph() self.vm = ElfMachine(input_cb=self.move, output_cb=self.paint, mem_size=4096) # 0: The repair droid hit a wall. Its position has not changed. # 1: The repair droid has moved one step in the requested direction. # 2: The repair droid has moved one step in the requested direction; its new position is the location of the oxygen system. self.status = {} def move(self, *args, **kwargs): loc = self.grid[self.pos[0]+self.dir_db[self.dir][0],self.pos[1]+self.dir_db[self.dir][1]] if loc == 0: if self.dir == 1: self.dir = 3 elif self.dir == 3: self.dir = 2 elif self.dir == 2: self.dir = 4 elif self.dir == 4: self.dir = 1 # plt.figure() # grid = self.grid.copy() # grid[self.pos] = 5 # plt.imshow(grid) # plt.show() elif loc == 1: oldpos = self.pos self.pos = self.pos[0]+self.dir_db[self.dir][0],self.pos[1]+self.dir_db[self.dir][1] self.G.add_edge(oldpos, self.pos) # print('Added',[oldpos, self.pos]) if self.dir == 1: self.dir = 4 elif self.dir == 3: self.dir = 1 elif self.dir == 2: self.dir = 3 elif self.dir == 4: self.dir = 2 elif loc == 2: oldpos = self.pos self.pos = self.pos[0]+self.dir_db[self.dir][0],self.pos[1]+self.dir_db[self.dir][1] self.G.add_edge(oldpos, self.pos) # print('Added',[oldpos, self.pos]) print('Found at',self.pos) # plt.figure() # grid = self.grid.copy() # grid[self.pos] = 5 # plt.imshow(grid) # plt.show() self.dist = len(nx.shortest_path(self.G, source=self.start, target=self.pos)) - 1 print('Current dist: {}'.format(self.dist)) self.two_pass += 1 if self.two_pass == 2: self.vm.finished = True # try: # except nx.NetworkXNoPath: # nx.draw(self.G) # plt.show() return self.dir def paint(self, x): self.grid[self.pos[0]+self.dir_db[self.dir][0],self.pos[1]+self.dir_db[self.dir][1]] = x def run(self,x): self.vm.run_program(x) return self.dist, self.G, self.pos
def part_two(x): '''Solves part two''' global a, b, c, d, dust a = [] b = [] dust = 0 def draw(x): global a, b, dust print(chr(x), end='') if x == 10: a.append(b[:]) b = [] elif x > 255: dust = x else: b.append(x) c = 0 d = 0 def traverse(*args, **kwargs): global c, d p = 'A,B,A,B,C,A,B,C,A,C\n' A = 'R,6,L,6,L,10\n' B = 'L,8,L,6,L,10,L,6\n' C = 'R,6,L,8,L,10,R,6\n' disp = 'n\n' if c == 0: print(d, len(p)) ret = p[d] d += 1 if d == len(p): c = 1 d = 0 return ord(ret) elif c == 1: ret = A[d] d += 1 if d == len(A): c = 2 d = 0 return ord(ret) elif c == 2: ret = B[d] d += 1 if d == len(B): c = 3 d = 0 return ord(ret) elif c == 3: ret = C[d] d += 1 if d == len(C): c = 4 d = 0 return ord(ret) elif c == 4: ret = disp[d] d += 1 if d == len(disp): c = 5 d = 0 return ord(ret) return ord(input('> ')) vm = ElfMachine(output_cb=draw, input_cb=traverse, mem_size=4096) x[0] = 2 vm.run_program(x) # print(c,d) # m = np.array(a[:-1]) # j = find_junctions(m) return dust