Exemple #1
0
class SpringDroid:

    def __init__(self) -> None:
        t = open('../resources/input_21.txt')
        lines = t.readlines()
        t.close()
        program = list(map(lambda x: int(x), lines[0].split(sep=',')))
        self.computer = IntcodeComputer(program)

    def run_spring_script(self, spring_script: [str]):
        mem, out, exit_code = self.computer.run_program()

        print(SpringDroid.decode(out))
        for line in spring_script:
            int_code = SpringDroid.encode(line)
            mem, out, exit_code = self.computer.run_program(input=int_code, reset_memory=False, reset_pointer=False, reset_relative_pointer=False)
        if exit_code == 1:
            print(SpringDroid.decode(out))
        else:
            print('{}{}'.format(SpringDroid.decode(out[:-1]), out[-1]))

    @staticmethod
    def decode(code: str):
        return reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), code))

    @staticmethod
    def encode(code: str):
        return list(map(lambda x: ord(x), code))
Exemple #2
0
 def test_result_for_part_two_day_five(self):
     t = open('../resources/input_5.txt')
     lines = t.readlines()
     t.close()
     original_inputs = list(map(lambda x: int(x), lines[0].split(sep=',')))
     computer = IntcodeComputer(original_inputs)
     computer.run_program(input=[5])
Exemple #3
0
    def __init__(self) -> None:
        t = open('resources/input_25.txt')
        lines = t.readlines()
        t.close()
        program = list(map(lambda x: int(x), lines[0].split(sep=',')))

        self.computer = IntcodeComputer(program)
Exemple #4
0
 def __init__(self, ) -> None:
     t = open('../resources/input_17.txt')
     lines = t.readlines()
     t.close()
     program = list(map(lambda x: int(x), lines[0].split(sep=',')))
     self.computer = IntcodeComputer(program)
     self.image = ''
     self.intersections = list()
Exemple #5
0
    def test_opcode_3(self):
        inputs = [3, 2, 0]
        expected_memory = [3, 2, 99]

        computer = IntcodeComputer(inputs)
        outputs = computer.run_program(input=[99])[0]

        assert_equal(outputs, expected_memory)
Exemple #6
0
    def test_result_for_first_part(self):
        t = open('../resources/input_2.txt')
        lines = t.readlines()
        t.close()
        inputs = list(map(lambda x: int(x), lines[0].split(sep=',')))

        computer = IntcodeComputer(inputs)
        result = computer.run_program(parameters=[12, 2])[0]
        print('The value is: ' + str(result[0]))
Exemple #7
0
    def test_result_part_two_day_nine(self):
        t = open('../resources/input_9.txt')
        lines = t.readlines()
        t.close()
        original_inputs = list(map(lambda x: int(x), lines[0].split(sep=',')))
        computer = IntcodeComputer(original_inputs)

        output = computer.run_program(input=[2])[1]
        print('Resulting coordinates of the distress signal: {}'.format(output))
Exemple #8
0
    def test_result_part_one_day_nine(self):
        t = open('../resources/input_9.txt')
        lines = t.readlines()
        t.close()
        original_inputs = list(map(lambda x: int(x), lines[0].split(sep=',')))
        computer = IntcodeComputer(original_inputs)

        output = computer.run_program(input=[1])[1]
        print('Result: {}'.format(output))
        assert_equal(output, [3409270027])
Exemple #9
0
    def test_compare(self):
        ### manual testing of various programs, check printed output to verify

        inputs = [
            3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31,
            1106, 0, 36, 98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104,
            999, 1105, 1, 46, 1101, 1000, 1, 20, 4, 20, 1105, 1, 46, 98, 99
        ]
        computer = IntcodeComputer(inputs)
        computer.run_program(input=[100])
Exemple #10
0
    def test_run_program(self):
        inputs = [
            ([1, 0, 0, 0, 99], [2, 0, 0, 0, 99]),
            ([2, 3, 0, 3, 99], [2, 3, 0, 6, 99]),
            ([2, 4, 4, 5, 99, 0], [2, 4, 4, 5, 99, 9801]),
            ([1, 1, 1, 4, 99, 5, 6, 0, 99], [30, 1, 1, 4, 2, 5, 6, 0, 99])
        ]

        for input_tuple in inputs:
            computer = IntcodeComputer(input_tuple[0])
            result = computer.run_program()[0]
            assert_equal(result, input_tuple[1])
Exemple #11
0
class SantaRescue:
    def __init__(self) -> None:
        t = open('resources/input_25.txt')
        lines = t.readlines()
        t.close()
        program = list(map(lambda x: int(x), lines[0].split(sep=',')))

        self.computer = IntcodeComputer(program)

    def run(self, command: str):
        encoded = SantaRescue.encode(command)

        mem, out, exit_code = self.computer.run_program(input=encoded, reset_memory=False,
                                                        reset_pointer=False, reset_relative_pointer=False)
        decoded = SantaRescue.decode(out)
        print(decoded)



    @staticmethod
    def decode(code: str):
        return reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), code))

    @staticmethod
    def encode(code: str):
        return list(map(lambda x: ord(x), code))
Exemple #12
0
    def test_result_for_second_part(self):
        expected_value = 19690720

        t = open('../resources/input_2.txt')
        lines = t.readlines()
        t.close()
        original_inputs = list(map(lambda x: int(x), lines[0].split(sep=',')))

        result = 0
        computer = IntcodeComputer(original_inputs)
        for i in range(100):
            for j in range(100):

                result = computer.run_program(parameters=[i, j])[0]
                if result[0] == expected_value:
                    print('noun: ' + str(i) + ' verb: ' + str(j))
                    print('result is: ' + str(100 * i + j))
                    break
            if result[0] == expected_value:
                break
    def __init__(self) -> None:
        t = open('../resources/input_23.txt')
        lines = t.readlines()
        t.close()
        program = list(map(lambda x: int(x), lines[0].split(sep=',')))

        self.computers = [IntcodeComputer(program) for i in range(50)]
        self.packet_queues = [list() for i in range(50)]
        for c in range(50):
            mem, out, exit_code = self.computers[c].run_program(input=[c])
            print('Booting computer {}: {}'.format(c, out))
        self.nat_storage = None
        self.nat_sent_y = list()
class RepairDroid:
    def __init__(self, program: [int]) -> None:
        self.computer = IntcodeComputer(program)
        self.map = dict()

    def find(self):
        seen = dict()
        pos = np.array((0, 0))
        all_seen = False
        while not all_seen:
            has_to_backtrack = True
            for i in [1, 4, 2, 3]:
                if tuple(pos + RepairDroid.direction(i)) not in seen:
                    has_to_backtrack = False
                    mem, out, exit_code = self.computer.run_program(
                        input=[i],
                        reset_relative_pointer=False,
                        reset_pointer=False,
                        reset_memory=False)
                    assert len(out) == 1
                    out_code = out[0]
                    if out_code == 0:
                        seen[tuple(pos + RepairDroid.direction(i))] = '#'
                    elif out_code == 1:
                        pos += RepairDroid.direction(i)
                        seen[tuple(pos)] = '.'
                    elif out_code == 2:
                        pos += RepairDroid.direction(i)
                        seen[tuple(pos)] = '+'
                    break

            if has_to_backtrack:
                path = list()
                path.append(tuple(pos))
                commands = RepairDroid.backtrack(seen, path, list())
                for i in commands[0]:
                    mem, out, exit_code = self.computer.run_program(
                        input=[i],
                        reset_relative_pointer=False,
                        reset_pointer=False,
                        reset_memory=False)
                    if out[0] != 0:
                        pos += RepairDroid.direction(i)

                    else:
                        print('Backtracking failed!')
                all_seen = has_to_backtrack and not commands[0]

        RepairDroid.print_screen(seen, tuple(pos))

        self.map = seen

        tree = RepairDroid.BFS(seen)

        path_to_oxygen = list()

        while tree.parent:
            path_to_oxygen.append(tree.data[0])
            tree = tree.parent

        target_pos = None
        shortest_path_map = seen.copy()
        for pos in path_to_oxygen:
            if pos != (0, 0) and shortest_path_map[pos] != '+':
                shortest_path_map[pos] = 'X'
            elif shortest_path_map[pos] == '+':
                target_pos = pos
        RepairDroid.print_screen(shortest_path_map, tuple(pos))
        print('Target: {}'.format(target_pos))

        return path_to_oxygen, target_pos

    @staticmethod
    def BFS(map: dict):
        tree = Node(((0, 0), 'O'))
        discovered = list()
        q = list()
        discovered.append(tree.data[0])
        q.append(tree)
        while q:
            v = q.pop()
            if v.data[1] == '+':
                return v
            children = list()
            for i in range(1, 5):
                pos_to_check = tuple(
                    np.array(v.data[0]) + RepairDroid.direction(i))
                if pos_to_check in map and pos_to_check not in discovered:
                    if map[pos_to_check] != '#':
                        children.append(pos_to_check)
            for c in children:
                if c not in discovered:
                    discovered.append(c)
                    node = Node((c, map[c]))
                    v.add_node(v, node)
                    q.append(node)

    def oxygenate(self, oxygen_pos: tuple):
        pos_map = self.map.copy()
        pos_map[oxygen_pos] = 'O'
        minutes = 0
        #self.print_screen(pos_map, (0, 0))
        while '.' in pos_map.values():
            #self.print_screen(pos_map, (0, 0))
            minutes += 1

            pos_to_oxygenate = list()
            for pos in pos_map.keys():
                if pos_map[pos] == 'O':
                    pos_to_oxygenate.append(pos)

            for pos in pos_to_oxygenate:
                if pos_map[pos] == 'O':
                    for i in range(1, 5):
                        pos_to_check = tuple(
                            np.array(pos) + RepairDroid.direction(i))
                        if pos_to_check in pos_map and pos_map[
                                pos_to_check] == '.':
                            pos_map[pos_to_check] = 'O'
        return minutes

    @staticmethod
    def backtrack(seen: dict, path: list, path_commands: list):
        found = False
        for i in [1, 4, 2, 3]:
            if not found:
                field = np.array(path[-1:][0]) + RepairDroid.direction(i)
                if tuple(field) in seen:
                    if seen[tuple(field)] != '#' and tuple(field) not in path:
                        path.append(tuple(field))
                        path_commands.append(i)
                        path_commands, found = RepairDroid.backtrack(
                            seen, path, path_commands)
                else:
                    return path_commands, True
        if not found and path_commands:
            path_commands.pop()
            path.pop()
        return path_commands, found

    @staticmethod
    def direction(dir: int):
        if dir == 1:
            return np.array((0, -1))
        elif dir == 2:
            return np.array((0, 1))
        elif dir == 3:
            return np.array((-1, 0))
        elif dir == 4:
            return np.array((1, 0))

    @staticmethod
    def get_reverse_direction(dir: int):
        if dir == 1:
            return 2
        elif dir == 2:
            return 1
        elif dir == 3:
            return 4
        elif dir == 4:
            return 3

    @staticmethod
    def print_screen(seen: dict, pos: tuple):
        if seen and pos:
            x_max = max(map(lambda t: t[0], seen.keys()))
            x_min = min(map(lambda t: t[0], seen.keys()))
            y_max = max(map(lambda t: t[1], seen.keys()))
            y_min = min(map(lambda t: t[1], seen.keys()))

            for y in range(y_min, y_max + 1):
                line = ''
                for x in range(x_min, x_max + 1):
                    if (x, y) == (0, 0):
                        line += 'O'
                    else:
                        if (x, y) != pos:
                            if (x, y) in seen:
                                line += seen[(x, y)]
                            else:
                                line += ' '
                        else:
                            line += 'x'
                print(line)
            print('----------------------------------')
Exemple #15
0
 def test_opcode_9_and_relative(self):
     program = [109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99]
     computer = IntcodeComputer(program)
     print(computer.run_program()[1])
class TractorBeam:
    def __init__(self) -> None:
        t = open('../resources/input_19.txt')
        lines = t.readlines()
        t.close()
        program = list(map(lambda x: int(x), lines[0].split(sep=',')))
        self.computer = IntcodeComputer(program)

    def get_affected_fields(self, max_x: int, max_y: int):
        affected = 0
        for x in range(max_x):
            for y in range(max_y):
                mem, out, exit_code = self.computer.run_program(input=[x, y])
                if out:
                    if out[0] == 1:
                        affected += 1
                        print('{}, {} -> {}'.format(x, y, out))

        return affected

    def fit_ship(self):
        x = 0
        y = 0
        affected_area = set()
        left_edge = 0
        for y in range(1000):
            found_in_line = False
            for x in range(left_edge, 1000):
                mem, out, exit_code = self.computer.run_program(input=[x, y])
                if out:
                    if out[0] == 1:
                        if not found_in_line:
                            found_in_line = True
                            left_edge = x
                        affected_area.add((x, y))
                    elif out[0] == 0:
                        if found_in_line:
                            break
                if len(affected_area) >= 100 * 100:
                    for pos in affected_area:
                        xx = pos[0]
                        yy = pos[1]
                        if (xx + 99, yy) in affected_area and (
                                xx, yy + 99) in affected_area and (
                                    xx + 99, yy + 99) in affected_area:
                            return (xx, yy)

    def fit_better(self):
        left_edge = 0
        y = 0
        affected_area = list()
        while True:
            found_in_line = False
            for x in range(left_edge, left_edge + 100):
                mem, out, exit_code = self.computer.run_program(input=[x, y])
                if out[0] == 1:
                    if not found_in_line:
                        found_in_line = True
                        left_edge = x
                        for xx in range(left_edge, left_edge + 100):

                            mem, out, exit_code = self.computer.run_program(
                                input=[xx, y])
                            if out[0] == 1:
                                affected_area.append((xx, y))
                                if (xx - 100, y - 100) in affected_area:
                                    if (xx - 100, y) in affected_area and (
                                            xx, y - 100) in affected_area:
                                        return (xx - 100, y - 100)
                            elif out[0] == 0:
                                if found_in_line:
                                    #TractorBeam.print_beam(x, xx, True)
                                    break
                    break
            #if not found_in_line:
            #   TractorBeam.print_beam(left_edge, left_edge + 100, False)
            y += 1

    def fit_even_better(self):
        s_length = 99
        x = 0
        y = 100
        while True:
            while True:
                mem, out, exit_code = self.computer.run_program(input=[x, y])
                if out[0] == 1:
                    if self.computer.run_program(
                            input=[x + s_length, y - s_length])[1][0] == 1:
                        return x * 10000 + y - 99
                    else:
                        break
                else:
                    x += 1
            y += 1
            #13690873 wrong

    @staticmethod
    def print_beam(le, re, found):
        s = reduce(lambda l, r: l + r, ['.' for x in range(le)], '.')
        if found:
            s += reduce(lambda l, r: l + r, ['#' for x in range(le, re)], '.')
        else:
            s += reduce(lambda l, r: l + r, ['.' for x in range(le, re)], '.')
        print(s)
Exemple #17
0
 def __init__(self, game: [int]) -> None:
     self.computer = IntcodeComputer(game)
     self.parameters = [2]
     self.screen = [[' ' for x in range(24)] for y in range(42)]
Exemple #18
0
class Arcade:
    def __init__(self, game: [int]) -> None:
        self.computer = IntcodeComputer(game)
        self.parameters = [2]
        self.screen = [[' ' for x in range(24)] for y in range(42)]

    def run(self, input: int = None):
        if self.parameters:
            param = list()
            param.append(self.parameters.pop())
        else:
            param = None
        if input is not None:
            inp = [input]
        else:
            inp = None

        hi_score = 0
        exit_code = 1

        while exit_code != 0:
            mem, out, exit_code = self.computer.run_program(
                parameters=[2],
                input=inp,
                reset_memory=False,
                reset_pointer=False,
                reset_relative_pointer=False)

            p = 0
            ball_x, bally = 0, 0
            pad_x, pad_y = 0, 0
            while p + 3 <= len(out):
                c = '~'
                if out[p + 2] == 0:
                    c = ' '
                elif out[p + 2] == 1:
                    c = '#'
                elif out[p + 2] == 2:
                    c = 'X'
                elif out[p + 2] == 3:
                    c = '-'
                    pad_x = out[p]
                    pad_y = out[p + 1]
                elif out[p + 2] == 4:
                    c = 'O'
                    ball_x = out[p]
                    ball_y = out[p + 1]
                else:
                    c = out[p + 2]

                x = out[p]
                y = out[p + 1]
                if x == -1 and y == 0:
                    hi_score = out[p + 2]
                else:
                    self.screen[x][y] = c
                p += 3

            if ball_x > pad_x:
                inp = [1]
            elif ball_x < pad_x:
                inp = [-1]
            else:
                inp = [0]
            print('Highscore: {}'.format(hi_score))
            self.print_screen(self.screen)

    def print_screen(self, screen):
        for y in range(len(screen[0])):
            line = ''
            for x in range(len(screen)):
                line += screen[x][y]
            print(line)
Exemple #19
0
 def test_opcode_9_and_relative_2(self):
     program = [1102, 34915192, 34915192, 7, 4, 7, 99, 0]
     computer = IntcodeComputer(program)
     print(computer.run_program()[1])
Exemple #20
0
 def test_opcode_9_and_relative_3(self):
     program = [104, 1125899906842624, 99]
     computer = IntcodeComputer(program)
     print(computer.run_program()[1])
 def __init__(self, program: [int]) -> None:
     self.computer = IntcodeComputer(program)
     self.map = dict()
Exemple #22
0
    def test_opcode_4(self):
        inputs = [4, 2, 99]

        computer = IntcodeComputer(inputs)
        computer.run_program()
Exemple #23
0
class CameraSystem:
    def __init__(self, ) -> None:
        t = open('../resources/input_17.txt')
        lines = t.readlines()
        t.close()
        program = list(map(lambda x: int(x), lines[0].split(sep=',')))
        self.computer = IntcodeComputer(program)
        self.image = ''
        self.intersections = list()

    def show_image(self):
        mem, out, exit_code = self.computer.run_program(reset_memory=False, reset_pointer=False,
                                                        reset_relative_pointer=False)

        s = reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out))
        self.image = s
        print(s)

    def find_intersections(self):
        img = self.image
        length = self.image.index('\n') + 1
        height = int(len(self.image) / length)
        intersections = list()

        for y in range(height):
            for x in range(length):
                if 0 < y < height - 1 and 0 < x < length - 1:
                    if (img[x - 1 + y * length] == '#' and img[x + y * length] == '#' and img[x + 1 + y * length] == '#'
                            and img[x + (y - 1) * length] == '#' and img[x + (y + 1) * length] == '#'):
                        img = img[:x + y * length] + 'O' + img[x + 1 + y * length:]
                        intersections.append((x, y))

        print(img)
        self.intersections = intersections
        print('Sum of alignment params: {}'.format(np.array(list(map(lambda t: t[0] * t[1], intersections))).sum()))

    def rescue(self):
        self.computer.run_program(parameters=[2])

        main = 'B,B,A,C,B,C,A,C,B,A\n'
        A = 'L,6,L,4,R,8,R,8\n'
        B = 'L,4,L,10,L,6\n'
        C = 'L,6,R,8,L,10,L,8,L,8\n'

        main = self.to_input(main)
        a = self.to_input(A)
        b = self.to_input(B)
        c = self.to_input(C)

        mem, out, exit_code = self.computer.run_program(input=main, reset_memory=False, reset_pointer=False,
                                                        reset_relative_pointer=False)

        print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out)))

        mem, out, exit_code = self.computer.run_program(input=a, reset_memory=False, reset_pointer=False,
                                                        reset_relative_pointer=False)

        print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out)))

        mem, out, exit_code = self.computer.run_program(input=b, reset_memory=False, reset_pointer=False,
                                                        reset_relative_pointer=False)

        print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out)))

        mem, out, exit_code = self.computer.run_program(input=c, reset_memory=False, reset_pointer=False,
                                                        reset_relative_pointer=False)

        print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out)))

        mem, out, exit_code = self.computer.run_program(input=self.to_input('n\n'), reset_memory=False,
                                                        reset_pointer=False,
                                                        reset_relative_pointer=False)

        print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out[:-1])))

        print('Total space dust collected: {}'.format(out[-1]))

    def to_input(self, s):
        return list(map(lambda c: ord(c), s))

    @staticmethod
    def encode_LZW(s: str) -> [str]:
        codes = list()
        idx, off = 0, 1

        scanned = False
        while not scanned:
            sub = s[idx:idx + off]

            if sub not in codes:
                codes.append(sub)
                idx += off
                off = 1
            else:
                off += 1

            if idx + off > len(s):
                scanned = True
                codes.append(sub)

        return codes