Exemple #1
0
def part2(lines: list[str]):
    rotations = {
        "L": {
            90: counterclockwise_90,
            180: rotate,
            270: clockwise_90
        },
        "R": {
            90: clockwise_90,
            180: rotate,
            270: counterclockwise_90
        },
    }

    pos = (0, 0)
    waypoint = (10, 1)

    for line in lines:
        cmd = line[0]
        number = utils.ints(line)[0]
        if cmd == "F":
            pos = utils.tuple_add(pos, tuple(number * i for i in waypoint))
        elif cmd in "LR":
            waypoint = rotations[cmd][number](waypoint)
        elif cmd in DIRECTIONS.keys():
            waypoint = utils.tuple_add(
                waypoint, tuple(number * i for i in DIRECTIONS[cmd]))

    return abs(pos[0]) + abs(pos[1])
Exemple #2
0
def simulate_step(moons: List[Moon]) -> None:
    all_pairs = list(combinations(moons, 2))
    for a, b in all_pairs:
        a.change_velocity(b)

    for moon in moons:
        moon.position = tuple_add(moon.position, moon.velocity)
Exemple #3
0
def part1(lines: list[str]):
    rotations = "ESWN"
    dir_ = "E"
    pos = (0, 0)

    for line in lines:
        cmd = line[0]
        number = utils.ints(line)[0]
        if cmd == "F":
            pos = utils.tuple_add(pos,
                                  tuple(number * i for i in DIRECTIONS[dir_]))
        elif cmd in "LR":
            number = number // 90
            idx = rotations.index(dir_)
            m = 1 if cmd == "R" else -1
            idx += m * number
            dir_ = rotations[idx % 4]
        elif cmd in DIRECTIONS.keys():
            pos = utils.tuple_add(pos,
                                  tuple(number * i for i in DIRECTIONS[cmd]))

    return abs(pos[0]) + abs(pos[1])
Exemple #4
0
def main():
    input_txt = utils.get_input(24).rstrip()
    lines = input_txt.split("\n")

    map_ = defaultdict(bool)

    for line in lines:
        start = (0, 0, 0)
        i = 0
        while i < len(line):
            if line[i] in directions:
                start = utils.tuple_add(start, directions[line[i]])
                i += 1
            elif line[i:i + 2] in directions:
                start = utils.tuple_add(start, directions[line[i:i + 2]])
                i += 2
            else:
                raise ValueError

        map_[start] = not map_[start]

    print(sum(1 for k, v in map_.items() if v))
    part2(map_)
Exemple #5
0
def has_occupied_seat_in_direction(
    pos: tuple[int, int],
    direction: tuple[int, int],
    occupied: set[tuple[int, int]],
    empty: set[tuple[int, int]],
):
    new_x, new_y = utils.tuple_add(pos, direction)
    if new_x < 0 or new_x > MAX_X or new_y < 0 or new_y > MAX_Y:
        return None
    elif (new_x, new_y) in empty:
        return False
    elif (new_x, new_y) in occupied:
        return True
    else:
        return has_occupied_seat_in_direction((new_x, new_y), direction,
                                              occupied, empty)
Exemple #6
0
def part2(map_):
    for _ in range(100):
        to_be_checked = {t for t, v in map_.items() if v}
        for t in list(to_be_checked):
            to_be_checked.update(
                utils.tuple_add(t, d) for d in directions.values())

        new_map = defaultdict(bool)
        for t in to_be_checked:
            number_of_black_neighbors = calc_black_neighbors(map_, t)
            is_black = map_[t]
            if is_black and number_of_black_neighbors in (1, 2):
                new_map[t] = True
            elif not is_black and number_of_black_neighbors == 2:
                new_map[t] = True
        map_ = new_map

    print(sum(1 for t, v in map_.items() if v))
Exemple #7
0
def run_robot(intcode, starting_tile):
    board = defaultdict(int)

    machine = Machine(0, copy.copy(intcode), deque(), 0)
    machine.inputs.append(starting_tile)
    state = machine.state
    position = (0, 0)
    facing = Direction.UP

    while state != State.HALT:
        state, out = machine.run()

        if len(out) != 2:
            raise Exception(f"Output from intcode machine != 2: {len(out)}")
        if out[0] == 0:
            board[position] = 0
        elif out[0] == 1:
            board[position] = 1
        else:
            raise Exception(
                f"First output value does not indicate black or white: {out[0]}"
            )

        if out[1] != 0 and out[1] != 1:
            raise Exception(
                f"Second output value does not indicate left or right: {out[1]}"
            )

        facing = turn[(out[1], facing)]
        position = tuple_add(position, facing.value)

        if state == State.WAIT_FOR_INPUT:
            machine.out.clear()
            machine.inputs.append(board[position])
            continue

    return board
Exemple #8
0
def calculate_adjacent(pos: tuple[int, int]) -> set[tuple[int, int]]:
    return {utils.tuple_add(pos, dir_) for dir_ in DIRS}
Exemple #9
0
def calc_black_neighbors(map_, t):
    return sum([map_[utils.tuple_add(t, d)] for d in directions.values()])