Esempio n. 1
0
def sol1(ins):
    ins[1] = 12
    ins[2] = 2
    comp = Intcode(ins)
    comp.run(debug=False)

    return comp.ins[0]
Esempio n. 2
0
def sol1(code, dbg=False):
    colour = {}
    current_pos = [0, 0]
    current_dir = Dir(0)
    computer = Intcode(code, [])
    next_input = 0

    while not computer.done():
        computer.add_input(next_input)

        while not computer.done() and len(computer.outputs) < 2:
            computer.execute_command()

        if computer.done():
            break

        paint, d = computer.outputs
        current_dir = current_dir.pred() if d == 0 else current_dir.succ()
        computer.outputs = []

        colour[tuple(current_pos)] = paint
        current_pos[0] += current_dir.xy()[0]
        current_pos[1] += current_dir.xy()[1]
        next_input = colour.get(tuple(current_pos), 0)

    return len(colour)
Esempio n. 3
0
def sol2(data):
    """
    If (any of A, B or C are holes and D is ground)
    and (H is ground or (E is ground and I is ground))
    or (A is hole and D is ground)
    then jump
    """
    inp = """NOT A J
    NOT B T
    OR T J
    NOT C T
    OR T J
    AND D J
    NOT E T
    NOT T T
    AND I T
    OR H T
    AND T J
    NOT A T
    AND D T
    OR T J
    RUN
    """
    ascii_input = list(map(ord, inp))

    computer = Intcode(data, ascii_input)
    computer.simulate()

    if computer.outputs[-1] > 255:
        return computer.outputs[-1]

    output = ''.join(list(map(chr, computer.outputs)))
    print(output)
Esempio n. 4
0
def sol2(code, show_progress=False):
    colour = {}
    current_pos = [0, 0]
    current_dir = Dir(0)
    computer = Intcode(code, [])
    next_input = 1

    while not computer.done():
        computer.add_input(next_input)

        while not computer.done() and len(computer.outputs) < 2:
            computer.execute_command()

        if computer.done():
            break

        paint, d = computer.outputs
        current_dir = current_dir.pred() if d == 0 else current_dir.succ()
        computer.outputs = []

        colour[tuple(current_pos)] = paint
        current_pos[0] += current_dir.xy()[0]
        current_pos[1] += current_dir.xy()[1]
        next_input = colour.get(tuple(current_pos), 0)

        if show_progress:
            print(identifier(colour))
            print()
            sleep(0.05)

    return identifier(colour)
Esempio n. 5
0
def sol1(data, show=False):
    computer = Intcode(data)
    board = [None] * BOARD_SIZE
    dist = [None] * BOARD_SIZE
    
    for i in range(BOARD_SIZE):
        board[i] = [' '] * BOARD_SIZE
        dist[i] = [-1] * BOARD_SIZE

    d_x, d_y = BOARD_SIZE // 2, BOARD_SIZE // 2
    board[d_y][d_x] = 'D'
    dist[d_y][d_x] = 0
    last_inp = None
    oxygen = None
    cur_dir = Direction.UP
    cur_dist = 0

    moves = 0
    while (d_x, d_y) != (BOARD_SIZE // 2, BOARD_SIZE // 2) or moves == 0:
        out = computer.execute_command()

        if out is not None:
            if out >= 0:
                if out == 0:
                    w_x, w_y = move_droid((d_x, d_y), last_inp)
                    board[w_y][w_x] = '#'
                    # Hit wall, adjust to the right twice
                    cur_dir = cur_dir.right()
                    cur_dir = cur_dir.right()
                elif out == 1:
                    if moves == 0:
                        moves = 1
                    board[d_y][d_x] = '.' # Mark as safe
                    d_x, d_y = move_droid((d_x, d_y), last_inp) 

                    if dist[d_y][d_x] >= 0:
                        cur_dist = dist[d_y][d_x]
                    else:
                        cur_dist += 1
                        dist[d_y][d_x] = cur_dist
                elif out == 2:
                    d_x, d_y = move_droid((d_x, d_y), last_inp) 
                    oxygen = (d_x, d_y)
                    cur_dist += 1 # definitely wasn't there before, just increase
                    return cur_dist

                if show:
                    print_board(board, (d_x, d_y), oxygen)
                    print('Current distance:', cur_dist)
                    sleep(0.005)
            elif out == -2: # waiting for input
                cur_dir = cur_dir.left()
                last_inp = go_forward(cur_dir)
                computer.add_input(last_inp)

    return cur_dist
Esempio n. 6
0
def sol2(code, user_input=False, display=False):
    code[0] = 2
    computer = Intcode(code, user_input=user_input)

    blocks = []
    score = 0

    while not computer.done():
        if computer.is_input():
            score, move = simulate_board(blocks, *get_dimensions(blocks),
                                         display)

            if not user_input:
                computer.add_input(move)

        computer.execute_command()

        if len(computer.outputs) == 3:
            x, y, tile = computer.outputs
            blocks.append((x, y, tile))

            computer.outputs = []

    score, _ = simulate_board(blocks, *get_dimensions(blocks), display)

    return score
Esempio n. 7
0
def sol2(ins):
    for noun in range(100):
        for verb in range(100):
            new_ins = ins[:]
            new_ins[1] = noun
            new_ins[2] = verb

            comp = Intcode(new_ins)
            comp.run()

            if comp.ins[0] == 19690720:
                return 100 * noun + verb
Esempio n. 8
0
def retrieve_board(data, show=False):
    """
    Retrieve the whole board by sticking to the left wall
    until reaching the beginning
    """
    if show:
        print('Retrieving board...')

    computer = Intcode(data) # Otherwise the default list argument is overwritten
    board = [None] * BOARD_SIZE
    
    for i in range(BOARD_SIZE):
        board[i] = [' '] * BOARD_SIZE

    d_x, d_y = BOARD_SIZE // 2, BOARD_SIZE // 2
    board[d_y][d_x] = 'D'
    last_inp = None
    cur_dir = Direction.UP
    oxygen = None

    moves = 0
    while (d_x, d_y) != (BOARD_SIZE // 2, BOARD_SIZE // 2) or moves == 0:
        out = computer.execute_command()

        if out is not None:
            if out >= 0:
                if out == 0:
                    w_x, w_y = move_droid((d_x, d_y), last_inp)
                    board[w_y][w_x] = '#'
                    # Hit wall, adjust to the right twice
                    cur_dir = cur_dir.right()
                    cur_dir = cur_dir.right()
                elif out == 1:
                    if moves == 0:
                        moves = 1
                    board[d_y][d_x] = '.' # Mark as safe
                    d_x, d_y = move_droid((d_x, d_y), last_inp) 
                elif out == 2:
                    d_x, d_y = move_droid((d_x, d_y), last_inp) 
                    oxygen = (d_x, d_y)

                if show:
                    print_board(board, (d_x, d_y), oxygen)
                    sleep(0.01)
            elif out == -2: # waiting for input
                cur_dir = cur_dir.left()
                last_inp = go_forward(cur_dir)
                computer.add_input(last_inp)

    if show:
        print('Board retrieved')

    return board, oxygen
Esempio n. 9
0
def sol2(data, feed=False):
    """
    Manually computed input:
    ABABCBACBC
    A = L 12 L 8 R 10 R 10
    B = L 6 L 4 L 12
    C = R 10 L 8 L 4 R 10
    """
    # with open('board.txt', 'w') as f:
    #     for row in board:
    #         f.write(row.__str__() + '\n')
    data[0] = 2
    main_routine = 'A,B,A,B,C,B,A,C,B,C'
    routine_a = 'L,12,L,8,R,10,R,10'
    routine_b = 'L,6,L,4,L,12'
    routine_c = 'R,10,L,8,L,4,R,10'
    feed_char = 'y' if feed else 'n'
    input_str = '\n'.join(
        [main_routine, routine_a, routine_b, routine_c, feed_char]) + '\n'
    inputs = [ord(c) for c in input_str]
    computer = Intcode(data, inputs=inputs)

    while not computer.done():
        computer.execute_command()

        if computer.outputs[-2:] == [10, 10] and feed:
            print('\n' * 100)
            print(''.join([chr(i) for i in computer.outputs]), end='')
            computer.outputs = []

    return computer.outputs[-1]
Esempio n. 10
0
def sol1(data):
    computer = Intcode(data)
    board = [[]]

    while not computer.done():
        computer.execute_command()

        if computer.outputs:
            out = computer.outputs.pop()

            if out == 10:
                board.append([])
            else:
                board[-1].append(chr(out))

    while not board[-1]:
        board.pop()

    result = 0

    for y, row in enumerate(board):
        if y == 0 or y == len(board) - 1:
            continue

        for x, c in enumerate(row):
            if c != '#' or x == 0 or x == len(row) - 1:
                continue

            neighbours = 0

            for nx, ny in [(x - 1, y), (x + 1, y), (x, y + 1), (x, y - 1)]:
                if board[ny][nx] == '#':
                    neighbours += 1

            if neighbours == 4:
                result += x * y

    return result
Esempio n. 11
0
def sol1(data, show_board=False):
    if show_board:
        board = []

        for _ in range(50):
            board.append(['.'] * 50)

    result = 0
    for x in range(50):
        for y in range(50):
            computer = Intcode(data[:], [x, y])
            computer.simulate()

            if computer.outputs[-1] == 1:
                result += 1

                if show_board:
                    board[y][x] = '#'

    if show_board:
        print_board(board)

    return result 
Esempio n. 12
0
def sol1(data):
    """
    If any of A, B or C are holes and D is ground
    then jump
    """
    inp = """NOT A J
    NOT B T
    OR T J
    NOT C T
    OR T J
    AND D J
    WALK
    """
    ascii_input = list(map(ord, inp))

    computer = Intcode(data, ascii_input)
    computer.simulate()

    if computer.outputs[-1] > 255:
        return computer.outputs[-1]

    output = ''.join(list(map(chr, computer.outputs)))
    print(output)
Esempio n. 13
0
def sol1(ins):
    comps = {i: Intcode(ins[:], inputs=[i]) for i in range(50)}

    while True:
        for i, comp in comps.items():
            comp.execute(wait_input=False, debug=False)

            if len(comp.outputs) == 3:
                dest, x, y = comp.outputs

                if dest == 255:
                    return y

                comp.outputs = []
                comps[dest].inputs.put(x)
                comps[dest].inputs.put(y)
Esempio n. 14
0
def guesses_lol(ins):
    # Get to the state right before the pressure plate with all items
    comp = Intcode(ins, inputs=list(map(ord, COLLECT_ALL_ITEMS)))
    comp.run()
    # Save this state
    pc = comp.pc
    rel_base = comp.rel_base

    for dropped in range(1, len(ITEMS)):
        for comb in combinations(ITEMS, dropped):
            comp = Intcode(ins[:])
            comp.pc = pc
            comp.rel_base = rel_base

            for item in comb:
                for c in drop(item):
                    comp.inputs.put(c)

            for c in map(ord, "east\n"):
                comp.inputs.put(c)

            print("Running with dropped ", comb)
            if comp.run(print_last=True):
                return
Esempio n. 15
0
def sol1(code):
    computer = Intcode(code)

    blocks = 0

    while not computer.done():
        computer.execute_command()

        if len(computer.outputs) == 3:
            x, y, tile = computer.outputs
            computer.outputs = []

            if tile == 2:
                blocks += 1

    return blocks
Esempio n. 16
0
def sol2(ins):
    NAT = (0, 0)

    comps = {i: Intcode(ins[:], inputs=[i]) for i in range(50)}
    no_sent = 0
    delivered_ys = set()

    while True:
        for i, comp in comps.items():
            status = comp.execute(wait_input=False, debug=False)

            if len(comp.outputs) == 3:
                no_sent = 0
                dest, x, y = comp.outputs
                comp.outputs = []

                if dest == 255:
                    NAT = (x, y)
                    continue

                comps[dest].inputs.put(x)
                comps[dest].inputs.put(y)

        no_sent += 1

        # We assume that all servers are waiting if no packet was sent in 700
        # executions. This is super slow (~30-ish seconds)
        if no_sent == 700:
            x, y = NAT
            print("NAT SENDING", x, y, "TO", 0)

            if y in delivered_ys:
                return y

            delivered_ys.add(y)
            comps[0].inputs.put(x)
            comps[0].inputs.put(y)

    return 0
Esempio n. 17
0
def sol2(ins):
    best = 0
    best_perm = []
    perm_count = 0

    for perm in permutations(range(5, 10)):
        initial_inputs = [[perm[i]] for i in range(5)]
        initial_inputs[0].append(0)

        programs = [Intcode(ins[:], int_inp) for int_inp in initial_inputs]

        finished = [False] * 5
        last_out = None
        last_meaningful_out = None

        while not all([p.done() for p in programs]):
            # Simulate one step of each
            for i, program in enumerate(programs):
                if program.done():
                    finished[i] = True

                    if all(finished):
                        return last_out

                    continue

                if last_out is not None and last_out >= 0:
                    last_meaningful_out = last_out
                    program.add_input(last_out)

                last_out = program.execute_command()

        if last_meaningful_out and last_meaningful_out > best:
            best = last_meaningful_out
            best_perm = perm

    return best
Esempio n. 18
0
def sol1(ins):
    guesses_lol(ins[:])
    comp = Intcode(ins[:], inputs=list(map(ord, WINNING_COMMANDS)))
    comp.run(interactive=True, print_last=True)
Esempio n. 19
0
def sol1(ins):
    comp = Intcode(ins, inputs=[1])
    comp.run()

    return comp.outputs[0]
Esempio n. 20
0
def sol2(ins):
    comp = Intcode(ins, inputs=[5])
    comp.run()

    return comp.outputs[-1]
Esempio n. 21
0
def sol1(ins):
    best = 0
    best_perm = []

    for perm in permutations(range(5)):
        amp_a = Intcode(ins[:], [perm[0], 0])
        out_a = amp_a.simulate()[0]

        amp_b = Intcode(ins[:], [perm[1], out_a])
        out_b = amp_b.simulate()[0]

        amp_c = Intcode(ins[:], [perm[2], out_b])
        out_c = amp_c.simulate()[0]

        amp_d = Intcode(ins[:], [perm[3], out_c])
        out_d = amp_d.simulate()[0]

        amp_e = Intcode(ins[:], [perm[4], out_d])
        out_e = amp_e.simulate()[0]

        if out_e > best:
            best = out_e
            best_perm = perm

    return best
Esempio n. 22
0
def check_beam(data, x, y):
    computer = Intcode(data, [x, y])
    computer.simulate()

    return computer.outputs[-1]