예제 #1
0
    def __init__(self, fname='input.txt'):
        self.ic = IntcodeComputer(fname, allow_pausing=True)

        self.history = {(0, 0): 1}
        self.dir_tried = {(0, 0): [0, 0, 0, 0]}  # N, E, S, W
        self.junction_path_dirs = {(0, 0): []}
        self.output = -1
        self.itercount = 0
        self.direction = 'N'
        self.position = np.array([0, 0])
        self.pos_visited = {(0, 0): False}
        self.dir_dict = {'N': 1, 'S': 2, 'W': 3, 'E': 4}
        self.backtrack_dict = {
            1: 2,
            2: 1,
            3: 4,
            4: 3
        }  # keep track of the reverse direction
        self.rev_dir_dict = {1: 'N', 2: 'S', 3: 'W', 4: 'E'}
        self.try_dir_dict = {'N': 0, 'E': 1, 'S': 2, 'W': 3}
        self.rev_try_dir_dict = {0: 'N', 1: 'E', 2: 'S', 3: 'W'}
        self.add_dict = {
            'N': np.array([0, 1]),
            'S': np.array([0, -1]),
            'W': np.array([-1, 0]),
            'E': np.array([1, 0])
        }

        self.maze = np.zeros((201, 201)) - 1
        self.xmin = -100
        self.ymin = -100
        self.junctions_list = []
        self.prev_dir = -1
예제 #2
0
def part1(data):
    amp_program = data
    inputs = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    input_pointer = 0

    def input_function():
        nonlocal input_pointer
        output = inputs[input_pointer]
        input_pointer += 1
        return output

    phase_settings = permutations([0, 1, 2, 3, 4])
    outputs = []
    for phase_setting in phase_settings:
        input_pointer = 0
        inputs = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        for j in range(5):
            inputs[2 * j] = phase_setting[j]
        for amp in range(5):
            computer = IntcodeComputer(deepcopy(amp_program), input_function)
            computer.run_program()
            if amp == 4:
                outputs.append(computer.outputs[0])
                break
            inputs[2 * amp + 3] = computer.outputs[0]
    return max(outputs)
예제 #3
0
class Droid:
    """ Executes the given intcode program, to navigate through damaged hull"""

    def __init__(self, intcode: List[int]):
        self.intcode = intcode
        self.result = []
        self.instruction = None

    def to_ascii(self, instruction: str) -> List[int]:
        ascii_instruction = [ord(char) for char in instruction]
        return ascii_instruction + [10]

    def get_input(self):
        try:
            value = next(self.instruction)
        except :
            self.instruction = (ascii_char for ascii_char in self.to_ascii(input()))
            value = next(self.instruction)
        return value

    def generate_output(self, value: int):
        try :
            self.result.append(chr(value))
        except:
            self.result.append(str(value))
        print(''.join(self.result))
    
    def execute(self):
        self.intcode_computer = IntcodeComputer(self.intcode, self.get_input, self.generate_output)
        while self.intcode_computer.has_next():
            next(self.intcode_computer.process_intcode())
예제 #4
0
async def part1(grid_size: int):
    input = asyncio.Queue()
    output = asyncio.Queue()
    computer = IntcodeComputer('day19.txt', input, output)

    grid = [['?' for x in range(grid_size)] for y in range(grid_size)]
    affected_points = 0
    for x in range(grid_size):
        for y in range(grid_size):
            computer.reset()
            input.put_nowait(x)
            input.put_nowait(y)
            await computer.execute()
            result = output.get_nowait()

            if result == 1:
                affected_points += 1
                grid[y][x] = '#'
            else:
                grid[y][x] = '.'

    for line in grid:
        print(''.join(line))

    print(f'Part 1: {affected_points}')
예제 #5
0
파일: aoc_15.py 프로젝트: Airymon/aoc2019
 def __init__(self, program, visualize=0):
     self.computer = IntcodeComputer(program, [], "Arcade Cabinet")
     self.areamap = dict()
     self.visualize = visualize
     self.startpos = Position(0,0)
     self.areamap[self.startpos] = Field(self.startpos, 1, -1)
     self.currentpos = self.startpos
예제 #6
0
def main(data):
    powers = []
    for perm in permutations(range(5, 10)):
        a_in = LifoQueue()
        a_b = LifoQueue()
        b_c = LifoQueue()
        c_d = LifoQueue()
        d_e = LifoQueue()
        out = LifoQueue()
        a_in.put(0)
        a = IntcodeComputer(data, in_queue=a_in, out_queue=a_b, init=perm[0])
        t1 = Thread(target=a.run)
        t1.start()
        b = IntcodeComputer(data, in_queue=a_b, out_queue=b_c, init=perm[1])
        t2 = Thread(target=b.run)
        t2.start()
        c = IntcodeComputer(data, in_queue=b_c, out_queue=c_d, init=perm[2])
        t3 = Thread(target=c.run)
        t3.start()
        d = IntcodeComputer(data, in_queue=c_d, out_queue=d_e, init=perm[3])
        t4 = Thread(target=d.run)
        t4.start()
        e = IntcodeComputer(data, in_queue=d_e, out_queue=out, init=perm[4])
        t5 = Thread(target=e.run)
        t5.start()
        while True:
            result = out.get()
            if e.halt:
                powers.append(result)
                break
            else:
                a_in.put(result)
    print(max(powers))
예제 #7
0
class SpringDroid:
    """ Executes the given intcode program, to navigate through damaged hull"""

    def __init__(self, intcode: List[int]):
        self.intcode = intcode
        # Jum if :
        #   - 4 is ground
        #   - AND (1 empty or 2 empty or 3 empty)
        #   - AND (5 is ground or 8 is ground)
        self.program = ['NOT A T','NOT B J','OR J T','NOT C J','OR T J', 'AND D J', 'NOT E T','NOT T T', 'OR H T', 'AND T J', 'RUN']
        self.result = []
        self.instructions = (ascii_char for line in self.program for ascii_char in self.to_ascii(line) )

    def to_ascii(self, instruction: str) -> List[int]:
        ascii_instruction = [ord(char) for char in instruction]
        return ascii_instruction + [10]

    def get_input(self):
        return next(self.instructions)

    def generate_output(self, value: int):
        try :
            self.result.append(chr(value))
        except:
            self.result.append(str(value))
    
    def execute(self):
        self.intcode_computer = IntcodeComputer(self.intcode, self.get_input, self.generate_output)
        while self.intcode_computer.has_next():
            next(self.intcode_computer.process_intcode())
예제 #8
0
파일: aoc_11.py 프로젝트: Airymon/aoc2019
class EHPR():
    def __init__(self, program):
        self.painted = defaultdict(int)
        self.position = Position(0,0)
        self.direction = Direction.Up
        self.computer = IntcodeComputer(program, [], "Emergency Hull Painting Robot", 0)

    def set_start_color(self, color):
        self.painted[self.position] = color

    def move(self, command):
        new_direction = (Direction(((self.direction.value + 1) % 4)) if command
                            else Direction(((self.direction.value - 1) % 4)))
        new_position = Position(*(sum(x) for x in zip(self.position, movement[new_direction])))
        self.direction = new_direction
        self.position = new_position

    def paint_square(self, color):
        self.painted[self.position] = color

    def execute_step(self):
        self.computer.add_input(self.painted[self.position])
        self.computer.run_program()
        output = self.computer.get_output()
        color, command = output[-2:]
        self.paint_square(color)
        self.move(command)
예제 #9
0
def part1(data):
    def inf():
        return 0

    scanner = IntcodeComputer(data, inf)
    scanner.run_program()
    scaffold = [[]]
    for output in scanner.outputs:
        if output != 10:
            scaffold[-1].append(output)
        else:
            scaffold.append([])
    scaffold = scaffold[:-2]
    total = 0
    for y in range(len(scaffold) - 1):
        for x in range(len(scaffold[0]) - 1):
            if x == 0 or y == 0:
                continue
            if scaffold[y][x] in (35, 94):
                intersection = True
                for pair in ((1, 0), (0, 1), (-1, 0), (0, -1)):
                    if scaffold[y + pair[1]][x + pair[0]] == 46:
                        intersection = False
                if intersection:
                    total += x * y
    return total
예제 #10
0
def Day05(program_file, input, output=False):
    VM = IntcodeComputer(program_file, input)
    while not VM.halted:
        result = VM.run()
        if result is not None:
            diagnostic_code = result
    return diagnostic_code
예제 #11
0
class Arcade:
    """ Executes the given intcode program, to play a game"""
    def __init__(self, intcode: List[int]):
        self.intcode = intcode
        self.current_position = (0, 0)
        self.screen = defaultdict(int)
        self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                                self.generate_output)
        self.offset = 0
        self.score = 0

    def get_input(self):
        return 0

    def generate_output(self, value: int):
        if self.offset == 0:
            self.x = value
            self.offset += 1
        elif self.offset == 1:
            self.y = value
            self.offset += 1
        elif self.offset == 2:
            if self.x == -1 and self.y == 0:
                logging.warning(f"Setting score to {value}")
                self.score = value
            else:
                logging.warning(
                    f"Setting tile in {self.x},{self.y} with {value}")
                self.screen[(self.x, self.y)] = value
            self.offset = 0

    def execute(self):
        self.intcode_computer.execute()
예제 #12
0
def solution2(data: List[int]) -> int:
    computer = IntcodeComputer(data)
    instructions = [
        "NOT C J\n",
        "AND D J\n",
        "NOT H T\n",
        "NOT T T\n",
        "OR E T\n",
        "AND T J\n",
        "NOT A T\n",
        "OR T J\n",
        "NOT B T\n",
        "NOT T T\n",
        "OR E T\n",
        "NOT T T\n",
        "OR T J\n",
    ]
    for instruction in instructions:
        computer.send_long(instruction)
    computer.send_long("RUN\n")
    computer.run_until_blocked()
    while computer.has_output():
        value = computer.read()
        try:
            print(chr(value), end="")
        except ValueError:
            return value
예제 #13
0
 def __init__(self, intcode: List[int]):
     self.intcode = intcode
     self.current_position = (0, 0)
     self.screen = defaultdict(int)
     self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                             self.generate_output)
     self.offset = 0
     self.score = 0
예제 #14
0
 def __init__(self, intcode: List[int]):
     self.intcode = intcode
     self.current_position = (0, 0)
     self.orientation = (0, 1)
     self.painting_area = defaultdict(int)
     self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                             self.generate_output)
     self.waiting_for_direction = False
예제 #15
0
def main(data):
    ic = IntcodeComputer(data, init=2)
    ic.run()
    while True:
        try:
            print(ic.output)
        except Empty:
            break
예제 #16
0
파일: aoc_13.py 프로젝트: Airymon/aoc2019
 def __init__(self, program, free_play=False, auto=False, display=True):
     if free_play:
         program = program[:]
         program[0] = 2
     self.computer = IntcodeComputer(program, [], "Arcade Cabinet")
     self.gamestate = dict()
     self.ball, self.tile = None, None
     self.auto = auto
     self.display = display
예제 #17
0
def main(data):
    for system_id in (1, 5):
        ic = IntcodeComputer(data, init=system_id)
        ic.run()
        while True:
            try:
                print(ic.output)
            except Empty:
                break
예제 #18
0
def play(screen, program):
    if RENDER_GAME:
        curses.curs_set(0)
        y_max = 0
    computer = IntcodeComputer(program,
                               return_output=True,
                               return_before_input=True)
    current_score = 0
    game_tiles = {}
    while True:
        output = computer.run()
        if output is computer.sentinel_return:
            bx, px = ball_and_paddle_x(game_tiles)
            computer.append_inputs(-1 if bx < px else 1 if bx > px else 0)
            x = computer.run()
        else:
            x = output
        y = computer.run()
        tile_id = computer.run()
        if computer.halted():
            break
        if x == -1 and y == 0:
            current_score = tile_id
            if RENDER_GAME:
                screen.addstr(y_max + 2, 0, f"Score => {current_score}")
                screen.refresh()
        else:
            game_tiles[(x, y)] = tile_id
            if RENDER_GAME:
                y_max = max(y_max, y)
                screen.addstr(y, x, COMPONENTS[tile_id])
                screen.refresh()
                sleep(FRAME_RATE)
    return current_score
예제 #19
0
def part1(data):
    last_out = 1
    direction_pointer = 0
    DIRECTIONS = {1: (0, 1), 4: (1, 0), 2: (0, -1), 3: (-1, 0)}
    walls = set()
    current_pos = (0, 0)
    to_input = 1

    def turn_right():
        table = {1: 4, 2: 3, 3: 1, 4: 2}
        nonlocal to_input
        to_input = table[to_input]

    def turn_left():
        table = {1: 3, 2: 4, 3: 2, 4: 1}
        nonlocal to_input
        to_input = table[to_input]

    def inf():
        nonlocal to_input
        return to_input

    turtle = IntcodeComputer(data, inf)
    walls.add((current_pos[0], current_pos[1], 3))
    while True:
        turn_left()
        check_wall = turtle.get_next_output()
        while check_wall == 0:
            walls.add((current_pos[0] + DIRECTIONS[to_input][0], current_pos[1] + DIRECTIONS[to_input][1]))
            turn_right()
            check_wall = turtle.get_next_output()
        current_pos = (current_pos[0] + DIRECTIONS[to_input][0], current_pos[1] + DIRECTIONS[to_input][1])
        if check_wall == 2:
            walls.add((current_pos[0], current_pos[1], 2))
        if current_pos == (0, 0):
            break
    bounds = [0, 0, 0, 0]
    for wall in walls:
        if wall[0] < bounds[0]:
            bounds[0] = wall[0]
        if wall[0] > bounds[2]:
            bounds[2] = wall[0]
        if wall[1] < bounds[1]:
            bounds[1] = wall[1]
        if wall[1] > bounds[3]:
            bounds[3] = wall[1]
    maze = [[0 for j in range(bounds[2] - bounds[0] + 1)] for i in range(bounds[3] - bounds[1] + 1)]
    for wall in walls:
        if len(wall) == 3:
            maze[wall[1] - bounds[1]][wall[0] - bounds[0]] = wall[2]
        else:
            maze[wall[1] - bounds[1]][wall[0] - bounds[0]] = 1
    for line in maze:
        print("".join([str(x) for x in line]).replace("1", "█").replace("0", ' ').replace("2", "E"))
    return maze
예제 #20
0
def main(data):
    powers = []
    for perm in permutations(range(5)):
        q = LifoQueue()
        q.put(0)
        for phase in perm:
            ic = IntcodeComputer(data, in_queue=q, out_queue=q)
            q.put(phase)
            ic.run()
        powers.append(q.get())
    print(max(powers))
예제 #21
0
def solve(input):
    print("TEST ID 1")
    intcodeComputer = IntcodeComputer(input)
    output = intcodeComputer.run(input_values=[1])
    print("diagnostic code: " + str(output))

    print("TEST ID 5")
    intcodeComputer = IntcodeComputer(input)
    output = intcodeComputer.run(input_values=[5])
    print("diagnostic code: " + str(output))
    return
예제 #22
0
    def __init__(self, prog):
        self.p    = direction.UP # pointing
        self.loc  = (0,0)
        self.grid = {}

        self.grid[self.loc] = 1

        self.brain   = IntcodeComputer([], prog)
        self.painted = []

        self.paint()
예제 #23
0
def part1_and_2(data):
    outputs = []
    for i in (1, 2):

        def inf():
            return i

        computer = IntcodeComputer(data, inf)
        computer.run_program()
        outputs.append(computer.outputs[0])
    return outputs
예제 #24
0
 def manual_execute(self):
     user_input = input().split()
     self.x, self.y = int(user_input[0]), int(user_input[1])
     while self.x != 'q':
         self.intcode_computer = IntcodeComputer(self.intcode,
                                                 self.get_input,
                                                 self.generate_output)
         while self.intcode_computer.has_next():
             next(self.intcode_computer.process_intcode())
         user_input = input().split()
         self.x, self.y = int(user_input[0]), int(user_input[1])
예제 #25
0
파일: aoc_19.py 프로젝트: Airymon/aoc2019
class FlyingDrone():
    def __init__(self, program):
        self.current_position = Position(0, 0)
        self.computer = IntcodeComputer(program, list(Position(0, 0)),
                                        "SpaceDroneNavigation")

    def navigate_to_pos(self, position):
        self.computer.add_prog_input(list(position))
        self.computer.run_program()
        output = self.computer.get_output()
        self.current_position = position
        return output[0]
예제 #26
0
class PaintingRobot:
    """ Executes the given intcode program, painting tiles based on its output"""
    def __init__(self, intcode: List[int]):
        self.intcode = intcode
        self.current_position = (0, 0)
        self.orientation = (0, 1)
        self.painting_area = defaultdict(int)
        self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                                self.generate_output)
        self.waiting_for_direction = False

    def get_input(self):
        logging.info(
            f"Reading tile {self.current_position} with color {self.painting_area[self.current_position]}"
        )
        return self.painting_area[self.current_position]

    def generate_output(self, x: int):
        if self.waiting_for_direction:
            if x == 0:
                # Turn left 90 degrees
                if self.orientation == (0, 1):
                    self.orientation = (-1, 0)
                elif self.orientation == (-1, 0):
                    self.orientation = (0, -1)
                elif self.orientation == (0, -1):
                    self.orientation = (1, 0)
                elif self.orientation == (1, 0):
                    self.orientation = (0, 1)
            else:
                if self.orientation == (0, 1):
                    self.orientation = (1, 0)
                elif self.orientation == (-1, 0):
                    self.orientation = (0, 1)
                elif self.orientation == (0, -1):
                    self.orientation = (-1, 0)
                elif self.orientation == (1, 0):
                    self.orientation = (0, -1)
            self.current_position = (self.current_position[0] +
                                     self.orientation[0],
                                     self.current_position[1] +
                                     self.orientation[1])
            self.waiting_for_direction = False
            logging.info(
                f"Updated orientation to  {self.orientation} and position to  {self.current_position}"
            )
        else:
            logging.info(f"Painting {self.current_position} with {x}")
            self.painting_area[self.current_position] = x
            self.waiting_for_direction = True

    def execute(self):
        self.intcode_computer.execute()
예제 #27
0
def part2(data):
    data[0] = 2
    pointer = 0

    def inf():
        nonlocal pointer
        pointer += 1
        return COMMANDS[pointer - 1]

    robot = IntcodeComputer(data, inf)
    robot.run_program()
    return robot.outputs[-1]
예제 #28
0
 def __init__(self, intcode: List[int]):
     self.intcode = intcode
     self.current_position = (0, 0)
     self.search_space = defaultdict(int)
     self.search_space[self.current_position] = -1
     self.unvisited_nodes = set()
     self.explored = defaultdict(int)
     self.solution_path = []
     self.image = None
     self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                             self.generate_output)
     self.moves = {1: (0, 1), 2: (0, -1), 4: (1, 0), 3: (-1, 0)}