예제 #1
0
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)
예제 #2
0
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
예제 #3
0
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
예제 #4
0
    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 = {}    
예제 #5
0
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
예제 #6
0
    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 = []
예제 #7
0
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()
예제 #8
0
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())
예제 #9
0
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
예제 #10
0
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
예제 #11
0
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()
예제 #12
0
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)
예제 #13
0
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
예제 #14
0
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
예제 #15
0
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