Esempio n. 1
0
    def initialize(self, change=None):
        """
        The Builder's main method. It stores all the changes that needs to be made
        in `self.details` for a file. Which would then be used to add Docstrings to.
        """
        result = dict()

        patches = []
        if change:
            patches = change.get('additions')

        for line in fileinput.input(self.filename):
            filename = fileinput.filename()
            lineno = fileinput.lineno()
            keywords = self.config.get('keywords')
            found = len(filter(lambda word: word.lstrip() in keywords, line.split(' '))) > 0

            if change and found:
                found = self._is_line_part_of_patches(lineno, line, patches)

            if not self.details.get(filename):
                self.details[filename] = dict()

            if found:
                length = get_file_lines(filename)
                result = self.extract_and_set_information(filename, lineno, line, length)
                if self.validate(result):
                    self.details[filename][result.name] = result
Esempio n. 2
0
	def get_layout(self, name):
		"""
		Returns the layout matching the name.
		"""
		layout = None
		if name in self.layouts:
			# Load the layout if it hasnt been yet
			if not self.layouts[name]:
				self.layouts[name] = utils.get_file_lines(self.layouts_dir + name)
			layout = self.layouts[name]
		return layout
Esempio n. 3
0
	def parse_templates(self, path):
		"""
		Looks for template syntax on each line and replaces it with the corresponding layout.
		"""
		new_lines = []
		lines = utils.get_file_lines(path)
		for line in lines:
			# check each line for the template syntax
			template, num_tabs = self.extract_template(line)
			if not template:
				new_lines.append(line)
				continue
			# concat the new lines added
			new_lines += self.eval_template(template, num_tabs)
		return new_lines
Esempio n. 4
0
from utils import get_file_lines


def parse_ticket(raw_ticket: str) -> int:
    table = str.maketrans('FBLR', '0101')
    binary = raw_ticket.translate(table)
    return int(binary, 2)


def part1(tickets: Set[int]) -> int:
    return max(tickets)
    

def part2(tickets: Set[int]) -> Optional[int]:
    def is_gap(x: int) -> bool:
        return x not in tickets and \
            x-1 in tickets and \
            x+1 in tickets

    for x in range(min(tickets)+1, max(tickets)):
        if is_gap(x):
            return x
    return None


if __name__ == '__main__':
    data = set(parse_ticket(t) for t in get_file_lines())
    print(part1(data))  # 911
    print(part2(data))  # 629
Esempio n. 5
0
File: day11.py Progetto: groselt/aoc
def part1(grid: list[list[int]], steps: int) -> int:
    flashes = 0
    for i in range(steps):
        _increase_grid(grid)
        _prepare_all_to_flash(grid)
        flashes += _flash_all(grid)
        # print('After step', i+1)
        # print_grid(grid)
        # print()
    return flashes


def part2(grid: list[list[int]]) -> int:
    octopus_count = len(grid) * len(grid[0])
    step = 0
    while True:
        step += 1
        _increase_grid(grid)
        _prepare_all_to_flash(grid)
        if _flash_all(grid) == octopus_count:
            return step


if __name__ == '__main__':
    grid = get_file_lines(transform=lambda line: [int(c) for c in line])
    X, Y = len(grid[0]), len(grid)
    STEPS = 100
    print(part1(grid, STEPS))  # 1719
    print(part2(grid) + STEPS)  # 232
Esempio n. 6
0
            elif floor_map[y][x] == '#' and _too_many_neighbours(x, y):
                new_row += 'L'
            else:
                new_row += floor_map[y][x]
        result.append(new_row)
    return result


def part1(floor_map: List[str]) -> int:
    neighbour_depth = 1
    neighbour_threshold = 4
    old_map = floor_map
    while (new_map := generate_next(old_map, neighbour_depth, neighbour_threshold)) != old_map:
        old_map = new_map
    return sum(x=='#' for x in chain.from_iterable(old_map))


def part2(floor_map: List[str]) -> int:
    neighbour_depth = max(len(floor_map), len(floor_map[0]))
    neighbour_threshold = 5
    old_map = floor_map
    while (new_map := generate_next(old_map, neighbour_depth, neighbour_threshold)) != old_map:
        old_map = new_map
    return sum(x=='#' for x in chain.from_iterable(old_map))


if __name__ == '__main__':
    raw_map = get_file_lines()
    print(part1(raw_map))  # 2481
    print(part2(raw_map))  # 2227
Esempio n. 7
0
File: day21.py Progetto: groselt/aoc
def part1(all_food: List[Food]) -> int:
    food = copy.deepcopy(all_food)
    while True:
        definite_allergens = get_definite_allergens(food)
        if not definite_allergens:
            break
        remove_ingredient_allergens(food, definite_allergens)
    return sum(len(f.ingredients) for f in food)


def part2(all_food: List[Food]) -> str:
    food = copy.deepcopy(all_food)
    all_allergens: List[Tuple[str, str]] = []
    while True:
        definite_allergens = get_definite_allergens(food)
        if not definite_allergens:
            break
        remove_ingredient_allergens(food, definite_allergens)
        all_allergens.extend(definite_allergens)
    ingredients = ','.join(x[0]
                           for x in sorted(all_allergens, key=lambda x: x[1]))
    return ingredients


if __name__ == '__main__':
    raw_food = [Food(line) for line in get_file_lines()]
    print(part1(raw_food))  # 2020
    print(part2(
        raw_food))  # bcdgf,xhrdsl,vndrb,dhbxtb,lbnmsr,scxxn,bvcrrfbr,xcgtv
Esempio n. 8
0
File: day13.py Progetto: groselt/aoc
def part1(now: int, buses: List[int]) -> int:
    wait_to_bus = {wait_time(now, bus): bus for bus in buses}
    shortest_wait = min(wait_to_bus.keys())
    return shortest_wait * wait_to_bus[shortest_wait]


def part2(buses: List[RankedBus]) -> int:
    timestamp = 0
    period = buses[0][1]
    for bus in buses[1:]:
        offset = bus[0] % bus[1]
        while wait_time(timestamp, bus[1]) != offset:
            timestamp += period
        period *= bus[1]
    return timestamp


if __name__ == '__main__':
    all_lines = get_file_lines()
    start_time = int(all_lines[0])

    active_buses = [int(t) for t in all_lines[1].split(',') if t != 'x']
    print(part1(start_time, active_buses))  # 3997

    ranked_buses = [
        RankedBus(i, int(b)) for i, b in enumerate(all_lines[1].split(','))
        if b != 'x'
    ]
    print(part2(ranked_buses))  # 500033211739354
Esempio n. 9
0
File: day14.py Progetto: groselt/aoc
    def expand_addresses(address: int, mask: str) -> Iterable:
        ''' Generator to generate all combinations in memory efficient way '''
        float_count = mask.count('X')
        original_address = to_bin(address)
        for combination in range(2**float_count):
            subs = to_bin(combination, float_count)
            new_address = []
            combi_i = 0
            for i in range(len(mask)):
                if mask[i] == '0':
                    new_address.append(original_address[i])
                elif mask[i] == '1':
                    new_address.append('1')
                else:
                    new_address.append(subs[combi_i])
                    combi_i += 1
            yield int(''.join(new_address), 2)

    memory: Dict[int, int] = dict()  # {addr: value}
    for instruction in instructions:
        for setting in instruction.settings:
            for address in expand_addresses(setting.address, instruction.mask):
                memory[address] = setting.value
    return sum(memory.values())


if __name__ == '__main__':
    raw_instructions = parse_instructions(get_file_lines())
    print(part1(raw_instructions))  # 10885823581193
    print(part2(raw_instructions))  # 3816594901962
Esempio n. 10
0
        default_debug_mode_setting = False
    elif default_debug_mode_setting not in [
            "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"
    ]:
        raise RuntimeError("default_debug_mode setting invalid")

    logger = logging.getLogger("chat_app")
    if default_debug_mode_setting is not False:
        logger.setLevel(getattr(logging, default_debug_mode_setting))
    if log_enabled_setting and log_file_name_setting:
        logger.addHandler(logging.FileHandler(log_file_name_setting))
    else:
        logger.addHandler(logging.NullHandler())

    root = tk.Tk()
    chatGUI = ChatGUI(root)
    chatGUI.clientSocket.connect(hostname_setting, port_setting,
                                 username_setting)
    if chatGUI.clientSocket.is_client_connected:
        SocketThreadedTask(chatGUI.clientSocket,
                           chatGUI.ChatWindow.update_chat_window).start()
    if test_file_setting is not None:
        commands = utils.get_file_lines(test_file_setting)
        commands_fixed = \
            filter(lambda command_line: not command_line.startswith("#"),
                   map(lambda command_line: command_line.strip(), commands))
        for command in commands_fixed:
            chatGUI.clientSocket.send(command)
            time.sleep(0.1)
    root.mainloop()
Esempio n. 11
0
        left_id = puzzle[row][0]
        for _ in range(PUZZLE_WIDTH - 1):
            for right in connections[left_id]:
                if tiles[right].orientate_and_connect(Tile.LEFT,
                                                      tiles[left_id].right):
                    puzzle[row].append(right)
                    left_id = right

    full_map = build_map(tiles, puzzle)

    mask = [
        '                  # ', '#    ##    ##    ###', ' #  #  #  #  #  #   '
    ]

    map_orientations = dict()
    for new_map in get_all_map_orientations(full_map):
        monster_count = get_mask_count(new_map, mask)
        map_orientations[monster_count] = new_map.copy()

    monster_count = max(map_orientations.keys())
    full_map = map_orientations[monster_count]
    mark_mask(full_map, mask)
    return sum(c == '#' for row in full_map for c in row)


if __name__ == '__main__':
    all_pieces = {piece.id: piece for piece in parse_pieces(get_file_lines())}

    print(part1(all_pieces))  # 18449208814679
    print(part2(all_pieces))  # 1559
Esempio n. 12
0
File: day12.py Progetto: groselt/aoc
            vector = self.waypoint - self.position
            self.waypoint = self.position + complex(
                vector.real * matrix[0][0] + vector.imag * matrix[0][1],
                vector.real * matrix[1][0] + vector.imag * matrix[1][1])


def parse_instruction(raw_instruction: str) -> Instruction:
    return Instruction(raw_instruction[0], int(raw_instruction[1:]))


def part1(instructions: List[Instruction]) -> int:
    navigation = Navigation(DIRECTION['E'], loose_waypoint=False)
    for instruction in instructions:
        navigation.apply(instruction)
    return navigation.distance()


def part2(instructions: List[Instruction]) -> int:
    navigation = Navigation(10 + 1j, loose_waypoint=True)
    for instruction in instructions:
        navigation.apply(instruction)
    return navigation.distance()


if __name__ == '__main__':
    all_instructions = [
        parse_instruction(instruction) for instruction in get_file_lines()
    ]
    print(part1(all_instructions))  # 445
    print(part2(all_instructions))  # 42495
Esempio n. 13
0
    def refresh_from_files(self):
        """
        Loads the DB data with data from the appropriate files
        self.banner from the file at BANNER_FILE path
        self.users from the file at USERS_FILE path
        self.banned_users from the file at BANNED_USERS_FILE path
        self.channels from the file at CHANNELS_FILE path
        :return:
        """
        # Load banner message from file
        try:
            with open(self.BANNER_FILE) as banner_file:
                self.banner = banner_file.read()
        except IOError:
            pass

        # Load users from file
        for user_line in utils.get_file_lines(self.USERS_FILE):
            try:
                user_line_splitted = user_line.split(None, 3)

                username = user_line_splitted[0]

                user_password = user_line_splitted[1]
                if user_password == '@':
                    user_password = ''

                user_level = user_line_splitted[2]
                if user_level not in ["user", "channelop", "sysop", "admin"]:
                    user_level = "user"

                user_is_banned = user_line_splitted[3]
                if user_is_banned == "false":
                    user_is_banned = False
                elif user_is_banned == "true":
                    user_is_banned = True
                else:
                    user_is_banned = bool(user_is_banned)

                self.users[username] = {
                    'username': username,
                    'password': user_password,
                    'level': user_level,
                    'banned': user_is_banned
                }
            except IndexError:
                continue

        # Load banned users from file
        self.banned_users = utils.get_file_lines(self.BANNED_USERS_FILE)

        # Load channels from file
        for channel_line in utils.get_file_lines(self.CHANNELS_FILE):
            try:
                channel_line_splitted = channel_line.split(None, 3)

                channel_name = channel_line_splitted[0]

                channel_password = channel_line_splitted[2]
                if channel_password == '@':
                    channel_password = ''

                channel_ops = channel_line_splitted[3]
                self.channels[channel_name] = {
                    'name': channel_name,
                    'description': channel_line_splitted[1],
                    'password': channel_password,
                    'channelops': [channel_op.strip()
                                   for channel_op in channel_ops.split(",")
                                   for channel_op in channel_op.split(None)]
                }
            except IndexError:
                pass
Esempio n. 14
0
File: day23.py Progetto: groselt/aoc
    current = original[0]
    removed = [0] * 3
    for _ in range(10_000_000):
        # remove
        removed[0] = ring[current]
        removed[1] = ring[removed[0]]
        removed[2] = ring[removed[1]]
        ring[current] = ring[removed[2]]

        # find destination
        destination = size if current == 1 else current - 1
        while destination in removed:
            destination = size if destination == 1 else destination - 1

        # insert
        ring[removed[2]] = ring[destination]
        ring[destination] = removed[0]

        # next
        current = ring[current]

    return ring[1] * ring[ring[1]]


if __name__ == '__main__':
    raw_data = [int(number) for number in list(get_file_lines()[0])]
    start_node = build_ring(raw_data)
    print(part1(start_node))  # 74698532
    print(part2(tuple(raw_data)))  # 286194102744
Esempio n. 15
0
            sub_hand1 = get_sub_hand(hand1)
            sub_hand2 = get_sub_hand(hand2)
            winner = play_recursive(sub_hand1, sub_hand2)
            move_cards_to_winner(hand1, hand2, winner)

    return 1 if hand1 else 2


def calc_score(hand: Hand) -> int:
    return sum((i + 1) * card for i, card in enumerate(reversed(hand)))


def part1(hand1: Hand, hand2: Hand) -> int:
    hand1, hand2 = hand1.copy(), hand2.copy()
    while hand1 and hand2:
        play_highest_card_wins(hand1, hand2)

    return calc_score(hand1 or hand2)


def part2(hand1: Hand, hand2: Hand) -> int:
    if play_recursive(hand1, hand2) == 1:
        return calc_score(hand1)
    return calc_score(hand2)


if __name__ == '__main__':
    raw_hand1, raw_hand2 = parse_input(get_file_lines())
    print(part1(raw_hand1, raw_hand2))  # 30138
    print(part2(raw_hand1, raw_hand2))  # 31587
Esempio n. 16
0
File: day08.py Progetto: groselt/aoc
        computer.step()
    return computer.ip < len(computer.instructions)


def part1(computer: Computer) -> int:
    assert run_to_loop_start(computer)
    return computer.accumulator


def part2(computer: Computer) -> Optional[int]:
    def make_new_instruction(old: Instruction) -> Instruction:
        new_operation = 'jmp' if old.operation == 'nop' else 'nop'
        return Instruction(new_operation, old.param)

    for i in range(len(computer.instructions)):
        computer.reset()
        old_instruction = computer.instructions[i]
        if old_instruction.operation in ('jmp', 'nop'):
            computer.instructions[i] = make_new_instruction(old_instruction)
            if not run_to_loop_start(computer):
                return computer.accumulator
            computer.instructions[i] = old_instruction
    return None


if __name__ == '__main__':
    raw_instructions = get_file_lines()
    main_computer = Computer(raw_instructions)
    print(part1(main_computer))  # 2051
    print(part2(main_computer))  # 2304
Esempio n. 17
0
File: day07.py Progetto: groselt/aoc
def can_bag_contain_colour(rules: Dict[str, List[Capacity]],
                           source_colour: str,
                           target_colour: str) -> bool:
    return any(
        child.colour == target_colour or
        can_bag_contain_colour(rules, child.colour, target_colour)
        for child in rules[source_colour]
    )


def count_contained(rules: Dict[str, List[Capacity]], colour: str) -> int:
    return sum(
        (child.total *
         count_contained(rules, child.colour) for child in rules[colour]),
        1
    )


def part1(rules: Dict[str, List[Capacity]]) -> int:
    return sum(can_bag_contain_colour(rules, b, 'shiny gold') for b in rules.keys())


def part2(rules: Dict[str, List[Capacity]]) -> int:
    return count_contained(rules, 'shiny gold') - 1  # exclude the bag itself


if __name__ == '__main__':
    bag_rules = dict(parse_rule(line) for line in get_file_lines())
    print(part1(bag_rules))  # 142
    print(part2(bag_rules))  # 10219
Esempio n. 18
0
 def parse_hosts_file(cls, path):
     "Parse a hosts file ``path`` and return a list of lines"
     return [HostLine(line) for line in get_file_lines(path)]
Esempio n. 19
0
    for next_number in numbers[25:]:
        if not is_valid(preamble, next_number):
            return next_number
        preamble.popleft()
        preamble.append(next_number)
    return 0


def part2(numbers: List[int], magic_number: int) -> int:
    def apply_range(
            fn: Callable[[Iterable], int],
            first_index: int,
            last_index: int):
        return fn(numbers[i] for i in range(first_index, last_index+1))

    start, end = 0, 1
    while True:
        total = apply_range(sum, start, end)
        if total == magic_number:
            return apply_range(min, start, end) + apply_range(max, start, end)
        if total < magic_number:
            end += 1
        else:
            start += 1


if __name__ == '__main__':
    raw_numbers = [int(i) for i in get_file_lines()]
    print(magic := part1(raw_numbers))  # 1639024365
    print(part2(raw_numbers, magic))  # 219202240
Esempio n. 20
0
from utils import get_file_lines


def calc_population(timers: dict, days: int) -> int:
    for _ in range(days):
        next_gen = defaultdict(int)
        for timer, count in timers.items():
            if timer == 0:
                next_gen[8] = count
                next_gen[6] += count
            else:
                next_gen[timer - 1] += count
        timers = next_gen
    return sum(timers.values())


def part1(timers: dict) -> int:
    return calc_population(timers, 80)


def part2(timers: list[int]) -> int:
    return calc_population(timers, 256)


if __name__ == '__main__':
    line = get_file_lines()[0]
    timers = Counter([int(i) for i in line.split(',')])
    print(part1(timers))  # 358214
    print(part2(timers))  # 1622533344325
Esempio n. 21
0
File: day17.py Progetto: groselt/aoc
    for coord in get_all_coordinates(min_coord, max_coord, dimensions):
        neighbour_count = 0
        for neighbour in get_neighbours(coord, dimensions):
            if cube[neighbour]:
                neighbour_count += 1
        if should_activate(cube[coord], neighbour_count):
            next_cube[coord] = True
    return next_cube


def part1(cube: Cube) -> int:
    for _ in range(6):
        cube = next_gen(cube, 3)
    return sum(state for state in cube.values())


def part2(cube: Cube) -> int:
    for _ in range(6):
        cube = next_gen(cube, 4)
    return sum(state for state in cube.values())


if __name__ == '__main__':
    raw_data = get_file_lines()

    initial_map_3d = parse_raw_data(raw_data, 3)
    print(part1(initial_map_3d))  # 240

    initial_map_4d = parse_raw_data(raw_data, 4)
    print(part2(initial_map_4d))  # 1180
Esempio n. 22
0
                              for pair in line.split())  # type: ignore
            passport.update(new_fields)
    if passport:
        yield passport


def contains_required_fields(entry: Dict) -> bool:
    return set(entry).issuperset(REQUIRED_FIELDS.keys())


def are_fields_valid(entry: Dict) -> bool:
    return all(
        validate(entry[key]) for key, validate in REQUIRED_FIELDS.items())


def part1(data: List[Dict]) -> int:
    return sum(contains_required_fields(entry) for entry in data)


def part2(data: List[Dict]) -> int:
    return sum(
        contains_required_fields(entry) and are_fields_valid(entry)
        for entry in data)


if __name__ == '__main__':
    parsed_data = list(parse_passports(get_file_lines()))

    print(part1(parsed_data))  # 228
    print(part2(parsed_data))  # 175
Esempio n. 23
0
File: day02.py Progetto: groselt/aoc
    return PasswordInfo(int1, int2, char, password)


def part1(password_info: List[PasswordInfo]) -> int:
    result: int = 0
    for info in password_info:
        counter = Counter(info.password)
        if info.char in counter and info.int1 <= counter[
                info.char] <= info.int2:
            result += 1
    return result


def part2(password_info: List[PasswordInfo]) -> int:
    result: int = 0
    for info in password_info:
        password_len = len(info.password)
        match1 = info.int1 <= password_len and info.password[info.int1 -
                                                             1] == info.char
        match2 = info.int2 <= password_len and info.password[info.int2 -
                                                             1] == info.char
        if match1 ^ match2:
            result += 1
    return result


if __name__ == '__main__':
    data = [parse_password_info(line) for line in get_file_lines()]
    print(part1(data))  # 474
    print(part2(data))  # 745
Esempio n. 24
0
File: day10.py Progetto: groselt/aoc
        Number of combinations is determined by considering each middle number as a bit
        which can be present (one) or not (zero): s**nrOfBits. Then subtract the number
        of groups of 3 consecutive bits: nrBits-2'''
    def are_consecutive(first: int, second: int) -> bool:
        return second - first == 1

    def combinations(nr_middle_bits: int) -> int:
        return 2**nr_middle_bits - max(nr_middle_bits - 2, 0)

    last_number = 0
    group_combinations: List[int] = [
    ]  # nr combinations for each consecutive group
    length = 0
    for next_number in numbers:
        if are_consecutive(last_number, next_number):
            length += 1
        elif length > 0:
            if length >= 2:
                group_combinations.append(combinations(length - 1))
            length = 0
        last_number = next_number
    if length >= 2:
        group_combinations.append(combinations(length))
    return math.prod(group_combinations)


if __name__ == '__main__':
    raw_numbers = sorted([int(i) for i in get_file_lines()])
    print(part1(raw_numbers))  # 2030
    print(part2(raw_numbers))  # 42313823813632
Esempio n. 25
0
#! /usr/bin/env python3.10

from utils import get_file_lines


def count_increase(depths: list[int], lookback: int) -> int:
    count = 0
    for i in range(lookback, len(depths)):
        if depths[i] > depths[i - lookback]:
            count += 1
    return count


def part1(depths: list[int]) -> int:
    return count_increase(depths, 1)


def part2(depths: list[int]) -> int:
    return count_increase(depths, 3)


if __name__ == '__main__':
    depths = get_file_lines(transform=int)
    print(part1(depths))  # 1791
    print(part2(depths))  # 1822
Esempio n. 26
0
    floors = [floor]
    for _ in range(20):
        floor = day24.next_floor(floor)
        floors.append(floor)

    col_count, row_count = get_grid_size(floors)
    x_offset = col_count // 2
    y_offset = row_count // 2
    center = complex(x_offset, y_offset)

    length = 10
    row_height = length * 1.7320508075688772935274463415059
    print('cols', col_count, 'width', 2 * length * col_count + 10)
    win = graphics.GraphWin('Part 2', 1.5 * length * col_count + 20,
                            row_count * row_height + 20)
    grid = HexagonGrid(5, 5, col_count, row_count, length)
    grid.draw(win)
    for floor in floors:
        print(win.getMouse())
        grid.reset_cells(set([center + pos for pos in floor.keys()]))
    print(win.getMouse())

    return sum(floor.values())


if __name__ == '__main__':
    raw_data = get_file_lines('input/day24.txt')
    raw_floor = day24.get_initial_state(raw_data)
    part1(raw_floor)
    part2(raw_floor)