예제 #1
0
    def get_map(cls, program: typing.List[int], draw_mode=False) -> "Map":
        computer = IntComputer(program, wait_after_output=True, wait_for_input=True)
        visited = defaultdict(int)
        droid_map = Map()
        steps = 0
    
        while not computer.finished and steps < 6000:
            direction = droid_map.get_best_direction(visited)
            #direction = int(input('Input: '))
            steps += 1
            computer.inputs = [direction]
            computer.run()
            while not computer.waiting:
                computer.run()
            output = computer.output

            if output == OUTPUT_WALL:
                droid_map.wall_hit([NORTH, SOUTH, WEST, EAST][direction - 1])

            if output == OUTPUT_FREE:
                [droid_map.north, droid_map.south, droid_map.west, droid_map.east][direction - 1]()
                droid_map.set_position(droid_map.position, FREE)
            
            if output == OUTPUT_OXYGEN:
                [droid_map.north, droid_map.south, droid_map.west, droid_map.east][direction - 1]()
                droid_map.set_position(droid_map.position, OXYGEN)
            
            visited[droid_map.position] += 1
        
            if draw_mode:
                droid_map.render()

        return droid_map
예제 #2
0
def part_2():
    output = 19690720
    for noun in range(100):
        for verb in range(100):
            computer = IntComputer(program)
            computer.run(noun, verb)
            if computer.memory[0] == output:
                return 100*noun + verb
예제 #3
0
class Game:
    def __init__(self, program, play=True, visual_mode=False):
        if play:
            program[0] = 2
        self.computer = IntComputer(program,
                                    wait_after_output=True,
                                    wait_for_input=True)
        self.visual_mode = visual_mode
        self.game_map = {}
        self.score = None

    def render(self):
        last_row = 0
        # reset the terminal window
        print("\033c", end="")
        for y, x in sorted(self.game_map.keys()):
            if last_row != y:
                print("")
            print(BLOCK_TYPES[self.game_map[(y, x)]], end="")
            last_row = y
        print("")

    def play_game(self):
        n = 0
        current_x = None
        current_y = None
        ball_x = None
        paddle_x = None
        current_tile = None
        while not self.computer.finished:
            n += 1
            output = self.computer.run()
            ready = not self.computer.finished and not self.computer.waiting
            if self.computer.waiting:  #waiting for input
                if paddle_x < ball_x:
                    i = RIGHT
                elif paddle_x > ball_x:
                    i = LEFT
                else:
                    i = NO_MOVE
                self.computer.inputs = [i]
                if self.visual_mode:
                    self.render()
                n -= 1  #reset to rerun with above input

            elif ready and n == 1:
                current_x = output
            elif ready and n == 2:
                current_y = output
            elif ready and n == 3:
                if current_x == -1 and current_y == 0:
                    self.score = output
                else:
                    current_tile == output
                    self.game_map[(current_y, current_x)] = current_tile
                    if current_tile == 4:  #ball
                        ball_x = current_x
                    if current_tile == 3:  #paddle
                        paddle_x = current_x
                n = 0
예제 #4
0
def part_2():
    grid = defaultdict(lambda _: '.')
    dim = 100
    cur_x, cur_y = 100, 100
    while True:
        # Do the corner
        bot = IntComputer(program,
                          wait_for_input=False,
                          wait_after_output=False)
        bot.inputs = [cur_x, cur_y]
        grid[(cur_x, cur_y)] = '#' if bot.run() else '.'
        del bot

        # do the edges
        for i in range(1, dim):
            bot_x = IntComputer(program,
                                wait_for_input=False,
                                wait_after_output=False)
            bot_y = IntComputer(program,
                                wait_for_input=False,
                                wait_after_output=False)
            bot_x.inputs = [cur_x - i, cur_y]
            bot_y.inputs = [cur_x, cur_y - i]
            grid[(cur_x - i, cur_y)] = '#' if bot_x.run() else '.'
            grid[(cur_x, cur_y - i)] = '#' if bot_y.run() else '.'
            del bot_x, bot_y

        #Check if we've achieved our goal
        for coord, state in grid.items():
            if coord[1] < 100:
                continue
            #start from a tractor spot, check that it's on the left edge,
            #go up and right 100 units to find the other corner and make sure it's a tractor spot,
            #and make sure that spot is a right edge
            if grid[coord] == '#' \
                and grid[(coord[0] - 1, coord[1])] == '.' \
                and grid[(coord[0] + 100, coord[1] - 100)] == '#' \
                and grid[(coord[0] + 101, coord[1] - 100)] == '.':
                return 10000 * coord[0] + (coord[1] - 100)
        cur_x += 1
        cur_y += 1
        dim += 1
예제 #5
0
def part_1():
    total_pull_nodes = 0
    graph = ''

    for y in range(50):
        for x in range(50):
            bot = IntComputer(program,
                              wait_for_input=False,
                              wait_after_output=False)
            bot.inputs = [x, y]
            output = bot.run()
            total_pull_nodes += output
            graph += '#' if output == 1 else '.'

        graph += '\n'

    print(graph)
    print(f"The total number of nodes that pull is: {total_pull_nodes} .")
예제 #6
0
def part_2():
    program = fh.csv_to_list('day17-input.txt')
    program[0] = 2
    ASCII = IntComputer(program, wait_after_output=False, wait_for_input=False)

    def to_ascii(l):
        return [ord(c) for c in l]

    # R, 8, R, 10, R, 10
    mov_func_A = ['R', ',', '8', ',', \
                    'R', ',', '1', '0', ',', \
                    'R', ',', '1', '0', '\n']
    mov_func_A = to_ascii(mov_func_A)

    # R, 4, R, 8, R, 10, R, 12
    mov_func_B = ['R', ',', '4', ',', \
                    'R', ',', '8', ',', \
                    'R', ',', '1', '0', ',', \
                    'R', ',', '1', '2', '\n']
    mov_func_B = to_ascii(mov_func_B)

    # R, 12, R, 4, L, 12, L, 12
    mov_func_C = ['R', ',', '1', '2', ',', \
                    'R', ',', '4', ',', \
                    'L', ',' ,'1', '2', ',',
                    'L', ',', '1', '2', '\n']
    mov_func_C = to_ascii(mov_func_C)

    # A, B, A, C, A, B, C, A, B, C
    main_func = ['A', ',', 'B', ',', \
                'A', ',', 'C', ',', \
                'A', ',', 'B', ',', \
                'C', ',', 'A', ',', \
                'B', ',', 'C', '\n']
    main_func = to_ascii(main_func)

    # y or n if you want to see a continuous feed of what's happening
    cont_feed = ['n', '\n']
    cont_feed = to_ascii(cont_feed)

    # input order: MAIN, MOV A, MOV B, MOV C, 
    ASCII.inputs = main_func + mov_func_A + mov_func_B + mov_func_C + cont_feed
    return ASCII.run()
예제 #7
0
def part_1():
    program = fh.csv_to_list('day17-input.txt')
    ASCII = IntComputer(program, wait_after_output=True)

    screen = ''
    while not ASCII.finished:
        output = ASCII.run()
        screen += chr(output)

    screen = screen.strip().split('\n')
    intersections = []

    for row in range(1,len(screen)-1):
        for col in range(1,len(screen[row])-1):
            char = screen[row][col]
            if char != '#':
                continue
            else:
                if screen[row-1][col] == '#' and \
                    screen[row+1][col] == '#' and \
                    screen[row][col-1] == '#' and \
                    screen[row][col+1] == '#':
                    intersections.append((row, col))
    return sum([r*c for r,c in intersections])
예제 #8
0
    else:
        return 0


def concatenate(l):
    s = ''
    for i in l:
        s += i
    return s


while True:
    current_color = getColor()
    #LOG.write(f"Currently at: {current_pos}, Color: {current_color}, Facing: {current_heading}\n")
    robot.inputs = [current_color]
    next_color = robot.run()
    #LOG.write(f"\tNext color: {next_color}\n")
    if robot.finished:  # After the last input, before halting, the robot pauses. Need to check if it's halted
        print("DONE")
        break
    turn = robot.run()

    #LOG.write(f"\tTurn: {turn}\n")
    grid[current_pos] = next_color
    current_heading = turnRobot(current_heading, turn)
    #LOG.write(f"\tPainted here: {grid[current_pos]}, Turned toward: {current_heading}\n")
    current_pos = moveRobot(current_pos, current_heading)

cols, rows = zip(*grid.keys())
min_cols = -min(cols) if min(cols) < 0 else 0
min_rows = -min(rows) if min(rows) < 0 else 0
예제 #9
0
def part_1():
    computer = IntComputer(program, inputs=[1])
    return computer.run()
예제 #10
0
def part(n):
    computer = IntComputer(program, inputs=[n])
    return computer.run()
예제 #11
0
class Robot():
    def __init__(self, program, visual_mode = False, manual_mode = False):
        self.robot = IntComputer(program, wait_after_output=True, wait_for_input=True)
        self.visual_mode = visual_mode
        self.manual_mode = manual_mode
        self._HEIGHT = 25
        self._WIDTH = 25
        self.starting_pos = (0,0)
        self.current_pos = self.starting_pos
        self.goal_pos = None
        self.map = {(x,y): 'UNK' for x in range(-self._WIDTH, self._WIDTH) for y in range(-self._HEIGHT,self._HEIGHT)}
        self.map[self.current_pos] = 'BOT'
        self.junctions = set()
        self.moves = []
        
    
    def render(self):
        last_row = 0
        # reset the terminal window
        print("\033c", end="")
        for x, y in sorted(self.map.keys(), key=itemgetter(1)):
            if last_row != y:
                print("")
            print(BLOCK_TYPES[self.map[(x,y)]], end="")
            last_row = y
        print("")

    def look_around(self):
        res = []
        for dir in ['N', 'S', 'W', 'E']:
            self.robot.inputs = [move_direction[dir]['bot_input']]
            vector = move_direction[dir]['vector']
            test_location = add(self.current_pos, vector)
            if self.map[test_location] != 'UNK':
                continue
            output = self.robot.run()
            if output == 0:
                self.map[test_location] = 'WALL'
            else:
                self.robot.inputs = [move_direction[opposite(dir)]['bot_input']]
                self.robot.run()
                res.append(dir)
        return res

    def move_robot(self, direction, backtracking=False):
        bot_input = move_direction[direction]['bot_input']
        vector = move_direction[direction]['vector']
        self.robot.inputs = [bot_input]
        output = self.robot.run()
        
        if output == 2:
            self.goal_pos = self.current_pos
            self.map[self.current_pos] = 'GOAL'
        else:
            self.map[self.current_pos] = 'VISITED' if not backtracking else self.map[self.current_pos]
            self.current_pos = add(self.current_pos, vector)
            self.map[self.current_pos] = 'BOT'
        

    def start(self):
        while self.current_pos != self.goal_pos:
            if self.visual_mode:
                self.render()
                # print(self.moves[-1:-20:-1])
                # print(self.junctions)
            user_input = None
            if self.manual_mode:
                user_input = input("Dir to Move: ")
                if user_input not in move_direction:
                    user_input = input("Dir to Move: ")
                    continue
            else: 
                possible_directions = self.look_around()
                if len(possible_directions) == 0:
                    if len(self.junctions) > 0:
                        self.map[self.current_pos] = 'DEAD'
                        while self.current_pos not in self.junctions:
                            #self.render()
                            #print(self.moves[-1:-10:-1])
                            self.move_robot(opposite(self.moves.pop(-1)))
                        continue
                    else:
                        self.map[self.starting_pos] = 'START'
                        self.map[self.goal_pos] = 'GOAL'
                        break
                elif len(possible_directions) == 1:
                    user_input = possible_directions[0]
                    self.junctions.discard(self.current_pos)
                else:
                    user_input = choice(possible_directions)
                    self.junctions.add(self.current_pos)

            self.move_robot(user_input)
            self.moves.append(user_input)
예제 #12
0
def part_1():
    computer = IntComputer(program)
    computer.run(12, 2)
    return computer.memory[0]