Beispiel #1
0
def part1(filename):
    memory = load_memory(filename, script=__file__)
    prog = Program(memory)
    run = prog.run_computer()

    rows = ''.join(map(chr, run)).split('\n')
    grid = {(x, y): cell for y, row in enumerate(rows)
            for x, cell in enumerate(row)}
    intersections = [(x, y) for x, y in grid if grid[x, y] == grid.get(
        (x+1, y)) == grid.get((x-1, y)) == grid.get((x, y+1)) == grid.get((x, y-1)) == '#']
    return sum(x*y for x, y in intersections)
Beispiel #2
0
def part2(filename):
    memory = load_memory(filename, script=__file__)
    memory[0] = 2
    input = parse_vararg_input(
        main='A,A,B,C,B,C,B,C,C,A',
        A='L,10,R,8,R,8',
        B='L,10,L,12,R,8,R,10',
        C='R,10,L,12,R,10',
        video='n'
    )
    prog = Program(memory, input)
    run = prog.run_computer()
    return list(run)[-1]
Beispiel #3
0
def solve(filename):
    memory = load_memory(filename, script=__file__)
    prog = Program(memory)
    run = prog.run_computer()

    grid = defaultdict(int, {(0, 0): 1})
    o2_distance = None
    o2_q = []

    def dfs(x, y, distance):
        nonlocal o2_distance, o2_q
        for (dir_code, return_code), (dx, dy) in DIRS.items():
            x1, y1 = x + dx, y + dy
            if (x1, y1) not in grid:
                prog.input.append(dir_code)
                status = next(run)
                grid[x1, y1] = status
                if status != 0:
                    dfs(x1, y1, distance + 1)
                    prog.input.append(return_code)
                    next(run)
        if grid[x, y] == 2:
            o2_distance = distance
            o2_q.append((x, y))

    dfs(0, 0, 0)

    o2_minutes = -1
    while o2_q:
        next_q = []
        for x, y in o2_q:
            for dx, dy in DIRS.values():
                x1, y1 = x + dx, y + dy
                if grid[x1, y1] == 1:
                    grid[x1, y1] = 2
                    next_q.append((x1, y1))
        o2_minutes += 1
        o2_q = next_q

    return (o2_distance, o2_minutes)
Beispiel #4
0
def part2(filename):
    memory = load_memory(filename, script=__file__)
    memory[0] = 2
    prog = Program(memory)
    grid = {}
    ball_x = paddle_x = score = None
    block_count = 0

    class PaddleInput:
        popleft = lambda self: sign(ball_x - paddle_x)

    prog.input = PaddleInput()

    for x, y, id in grouper(prog.run_computer(), 3):
        if (x, y) == (-1, 0):
            score = id
            if block_count == 0: return score
        else:
            if id == 2: block_count += 1
            elif id == 3: paddle_x = x
            elif id == 4: ball_x = x
            elif id == 0 and grid.get((x, y)) == 2: block_count -= 1
            grid[x, y] = id
    draw(grid, out=' |#-o')
Beispiel #5
0
class Computer():
    def __init__(self, memory, id):
        self.id = id
        self.prog = Program(memory, [id], default=-1)
        self.run = self.prog.run_computer()

    def start(self, notify):
        try:
            while True:
                addr = next(self.run)
                x = next(self.run)
                y = next(self.run)
                notify(self.id, addr, x, y)
        except:
            pass
Beispiel #6
0
def part1(filename):
    memory = load_memory(filename, script=__file__)
    grid = {(x, y): id
            for x, y, id in grouper(Program(memory, []).run_computer(), 3)}
    draw(grid, out=' █#-o')
    return sum(id == 2 for (x, y), id in grid.items())
Beispiel #7
0
def solve(filename, initial_color):
  memory = load_memory(filename, script=__file__)
  prog = Program(memory, [initial_color])
  return paint(prog, initial_color)
Beispiel #8
0
 def scan(self, x, y):
     return next(Program(self.memory, [x, y]).run_computer())
Beispiel #9
0
 def __init__(self, memory):
     self.prog = Program(memory, [])
     self.run = self.prog.run_computer()
Beispiel #10
0
class Game:
    def __init__(self, memory):
        self.prog = Program(memory, [])
        self.run = self.prog.run_computer()

    def get_output(self):
        return ''.join(until_str(map(chr, self.run), 'Command?'))

    def give_input(self, s):
        self.prog.input.extend(map(ord, s + '\n'))
        return self.get_output()

    def manipulate(self, action, item):
        return self.give_input(action + ' ' + item)

    def go(self, direction):
        return self.give_input(direction)

    def parse_output(self, output):
        title, doors, items, messages, mode = '', set(), [], [], ''
        for line in filter(None, output.split('\n')):
            if line.startswith('== ') and line.endswith(' =='):
                title, doors, items, mode = line[3:-3], set(), [], ''
            elif line == 'Doors here lead:':
                mode = 'doors'
            elif line == 'Items here:':
                mode = 'items'
            elif line.startswith('- '):
                if mode == 'doors': doors.add(line[2:])
                elif mode == 'items': items.append(line[2:])
            elif line != 'Command?':
                if mode != '':
                    messages.append(line)
        return title, doors, items, messages

    def solve(self):
        rooms, usable_items = {}, []

        def dfs(path, output):
            title, doors, items, _ = self.parse_output(output)
            for item in items:
                if item not in FORBIDDEN_ITEMS:
                    self.manipulate('take', item)
                    usable_items.append(item)
            if title not in rooms:
                rooms[title] = {'ch': '.', 'doors': {}, 'path': path}
                for d in doors:
                    title_dest = dfs(path + [d], self.go(d))
                    rooms[title]['doors'][d] = title_dest
                    if title_dest != title: self.go(OPPOSITE_DIRS[d])
            return title

        dfs([], self.get_output())

        for d in rooms[SECURITY]['path']:
            self.go(d)
        end_direction = next(d for d, name in rooms[SECURITY]['doors'].items()
                             if name == SECURITY)

        carrying = set(usable_items)
        for b in range(2**len(usable_items)):
            for i, item in enumerate(usable_items):
                if (1 << i) & b:
                    if item not in carrying:
                        self.manipulate('take', item)
                        carrying.add(item)
                else:
                    if item in carrying:
                        self.manipulate('drop', item)
                        carrying.remove(item)
            title, _, _, messages = self.parse_output(self.go(end_direction))
            if title != SECURITY: return int(messages[2].split(' ')[11])
Beispiel #11
0
def init_programs(combo, memory):
    return [(prog, prog.run_computer())
            for prog in (Program(memory, [val]) for val in combo)]
Beispiel #12
0
 def __init__(self, memory, id):
     self.id = id
     self.prog = Program(memory, [id], default=-1)
     self.run = self.prog.run_computer()
Beispiel #13
0
def part1(filename):
    memory = load_memory(filename, script=__file__)
    return list(Program(memory, [1]).run_computer())
Beispiel #14
0
def execute_springdroid(memory, input):
    prog = Program(memory, input)
    run = prog.run_computer()
    output = list(run)
    if output[-1] >= 256: return output[-1]
    print(''.join(map(chr, output)))