예제 #1
0
def parse_input(file_name):
    return {
        parent_bag_color: content_rules
        for parent_bag_color, content_rules in (
            _parse_bag_color_rule(bag_color_rule_string)
            for bag_color_rule_string in common.get_input_lines(file_name))
    }
예제 #2
0
def solve2():
    challenge_list = sorted(map(int, filter(len, get_input_lines(FILE_NUM))))

    for num1_index, first_num in enumerate(challenge_list):
        total = TARGET_SUM - first_num
        inner_prod = solve1(total, challenge_list[num1_index:])

        if inner_prod is not None:
            return inner_prod * first_num
예제 #3
0
def solve1(total=TARGET_SUM, challenge_list=None):
    if challenge_list is None:
        challenge_list = sorted(
            map(int, filter(len, get_input_lines(FILE_NUM))))

    for num in challenge_list:
        required_num = total - num

        if required_num in challenge_list:
            return num * required_num
예제 #4
0
def parse_input(file_name):
    return {
        output_chemical: {
            'output_amount': output_amount,
            'inputs': inputs,
        }
        for output_chemical, output_amount, inputs in (
            _parse_reaction(reaction_string)
            for reaction_string in common.get_input_lines(file_name))
    }
예제 #5
0
def parse_input(file_name):
    lookup = {
        'B': '1',
        'F': '0',
        'R': '1',
        'L': '0',
    }
    return [
        int(''.join(lookup[c] for c in line), 2)
        for line in common.get_input_lines(file_name)
    ]
예제 #6
0
def solve1_old():
    tree_lines = list(get_input_lines(FILE_NUM))
    line_length = len(tree_lines[0])
    tree_count = 0
    x = 0

    for (line_index, tree_line) in enumerate(tree_lines):
        tree_count += tree_line[x] == TREE_CHAR
        x = (x + 3) % line_length

    return tree_count
예제 #7
0
def solve2(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None,
                        HOME_DIR))
    instructions = get_instructions(lines)
    max_coord = get_max(instructions)
    field = get_field(max_coord + 1, max_coord + 1)

    populate_field(field, instructions, True)

    return get_danger_count(field)
예제 #8
0
def solve2(is_sample=False):
    lines = list(get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None, HOME_DIR))
    oxygen_lines, scrubber_lines = get_split(lines, 0)

    for digit in range(1, len(lines[0])):
        if len(oxygen_lines) > 1:
            oxygen_lines = get_split(oxygen_lines, digit)[0]
        if len(scrubber_lines) > 1:
            scrubber_lines = get_split(scrubber_lines, digit)[1]

    return int(oxygen_lines[0], 2) * int(scrubber_lines[0], 2)
예제 #9
0
def parse_input(file_name):
    settings = []
    for line in common.get_input_lines(file_name):
        index1, index2, char, password = re.search(
            r'(\d+)-(\d+) ([a-z]): ([a-z]+)', line).groups(0)
        indexes = [int(v) - 1 for v in (index1, index2)]
        settings.append({
            'indexes': indexes,
            'char': char,
            'password': password,
        })
    return settings
예제 #10
0
def solve1(is_sample=False, seats_callback=find_all_immediate_neighbors, taken_tolerance=4):
    lines = get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None)
    rows = [list(row) for row in lines]

    while check_has_changed(deepcopy(rows), rows, seats_callback, taken_tolerance):
        pass  # wait.. that's illegal!

    count_seats = sum([row.count(OCCUPIED_SEAT) for row in rows])

    print('\n'.join([' '.join(row) for row in rows]))

    return count_seats
예제 #11
0
def parse_input(file_name):
    settings = []
    for line in common.get_input_lines(file_name):
        span_start, span_end, char, password = re.search(
            r'(\d+)-(\d+) ([a-z]): ([a-z]+)', line).groups(0)
        span = [int(s) for s in (span_start, span_end)]
        settings.append({
            'span': span,
            'char': char,
            'password': password,
        })
    return settings
예제 #12
0
def solve1(x_steps=3, y_steps=1, tree_lines=None):
    if tree_lines is None:
        tree_lines = list(get_input_lines(FILE_NUM))

    line_length = len(tree_lines[0])
    tree_count = 0
    x = 0

    for line_index in range(0, len(tree_lines), y_steps):
        tree_count += tree_lines[line_index][x] == TREE_CHAR
        x = (x + x_steps) % line_length

    return tree_count
예제 #13
0
def get_diff_map():
    sorted_adapter_list = [0] + sorted(map(int, get_input_lines(FILE_NUM)))
    sorted_adapter_list += [sorted_adapter_list[-1] + 3]

    diff_map = {1: 0, 2: 0, 3: 0}
    latest_adapter = sorted_adapter_list[0]

    for adapter in sorted_adapter_list[1:]:
        diff_to_current = adapter - latest_adapter

        diff_map[diff_to_current] += 1
        latest_adapter = adapter

    return diff_map
예제 #14
0
def solve2():
    adapters = [0] + sorted(map(int, get_input_lines(FILE_NUM)))
    possible_edges = [1] + ([0] * (max(adapters)))

    for edge in adapters[1:]:
        reachable_edges = []

        for previous_index in range(edge - 3, edge):
            if previous_index >= 0:
                reachable_edges.append(possible_edges[previous_index])

        possible_edges[edge] = sum(reachable_edges)

    return possible_edges[-1]
예제 #15
0
def solve1(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None,
                        HOME_DIR))
    values = [int(x) for x in lines]
    increment_count = 0

    for value_index in range(1, len(values)):
        previous_value = values[value_index - 1]
        current_value = values[value_index]

        if current_value > previous_value:
            increment_count += 1

    return increment_count
예제 #16
0
def get_bus_lines_with_details(is_sample=False):
    _, bus_input = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None))
    bus_lines: List[str] = bus_input.split(',')[::-1]
    buses = []
    difference = 0

    for bus in bus_lines:
        if bus != OUT_OF_ORDER_BUS:
            bus_line = int(bus)
            buses.append([bus_line, difference % bus_line])

        difference += 1

    return buses
예제 #17
0
def solve2():
    numbers = list(map(int, get_input_lines(FILE_NUM)))
    invalid_number = find_invalid_number(numbers)

    for start_index in range(len(numbers) - 1):
        accumulated_sum = numbers[start_index]

        for last_index in range(start_index + 1, len(numbers)):
            accumulated_sum += numbers[last_index]

            if accumulated_sum == invalid_number:
                target_sequence = numbers[start_index:last_index + 1]

                return min(target_sequence) + max(target_sequence)
            elif accumulated_sum > invalid_number:
                break
예제 #18
0
def solve1(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None,
                        HOME_DIR))
    fishes = [int(x) for x in lines[0].split(',')]

    for step in range(80):
        fish_count = range(len(fishes))

        for fish_index in fish_count:
            fishes[fish_index] -= 1

            if fishes[fish_index] < 0:
                fishes[fish_index] = 6
                fishes.append(8)

    return len(fishes)
예제 #19
0
def solve1(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None))
    depart_time = int(lines[0])
    bus_lines = [
        int(bus) for bus in lines[1].split(',') if bus != OUT_OF_ORDER_BUS
    ]
    least_wait: int = max(bus_lines)
    best_bus_line = None

    for bus_line in bus_lines:
        current_wait = bus_line - depart_time % bus_line

        if least_wait > current_wait:
            least_wait = current_wait
            best_bus_line = bus_line

    return least_wait * best_bus_line
예제 #20
0
def solve2(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None,
                        HOME_DIR))
    h_pos, depth, aim = 0, 0, 0

    for line in lines:
        direction, units = line.split(' ')
        units = int(units)

        if direction == 'forward':
            h_pos += units
            depth += aim * units
        elif direction == 'up':
            aim -= units
        else:
            aim += units

    return h_pos * depth
예제 #21
0
def get_instructions():
    instructions = []
    jump_list = []

    for line in get_input_lines(FILE_NUM):
        instruction_type, val = line.split(' ')
        val = int(val)
        instruction_entry = [str(instruction_type), val]
        is_potential_jump = instruction_type in [
            INST_TYPES['JUMP_TO_LINE'], INST_TYPES['NO_OPERATION']
        ]

        instructions.append(instruction_entry)

        index = len(instructions) - 1
        jump_list.append([index] +
                         instruction_entry) if is_potential_jump else None

    return [instructions, jump_list]
예제 #22
0
def solve2_old():
    tree_lines = list(get_input_lines('03'))
    line_length = len(tree_lines[0])
    logic_list = [{
        'x': 0,
        'increment_by': 1,
        'check_every': 1,
        'count': 0
    }, {
        'x': 0,
        'increment_by': 3,
        'check_every': 1,
        'count': 0
    }, {
        'x': 0,
        'increment_by': 5,
        'check_every': 1,
        'count': 0
    }, {
        'x': 0,
        'increment_by': 7,
        'check_every': 1,
        'count': 0
    }, {
        'x': 0,
        'increment_by': 1,
        'check_every': 2,
        'count': 0
    }]

    for (line_index, tree_line) in enumerate(tree_lines):
        for logic_line in logic_list:
            check_modulo = logic_line['check_every']

            if line_index % check_modulo != 0:
                continue

            x = logic_line['x']

            logic_line['count'] += tree_line[x] == TREE_CHAR
            logic_line['x'] = (x + logic_line['increment_by']) % line_length

    return prod(map(lambda x: x.get('count'), logic_list))
예제 #23
0
def solve1(is_sample=False):
    lines = list(get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None, HOME_DIR))
    crab_pos = [int(x) for x in lines[0].split(',')]

    unique_pos = list(set(crab_pos))
    count_pos = [len([x for x in crab_pos if x == up]) for up in unique_pos]
    cost_pos = []

    for to_pos in unique_pos:
        current_cost = 0

        for from_index in range(len(unique_pos)):
            from_pos, count = unique_pos[from_index], count_pos[from_index]
            cost_per_unit = abs(to_pos - from_pos)

            current_cost += count * cost_per_unit

        cost_pos.append(current_cost)

    return min(cost_pos)
예제 #24
0
def solve2(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None,
                        HOME_DIR))
    total_count = 0

    for line in lines:
        numbers: list
        output: list
        numbers, output = [[sorted(list(y)) for y in x.split(' ')]
                           for x in line.split(' | ')]
        numbers.sort(key=lambda num: len(num))

        relevant_numbers = get_correct_nums(numbers)

        total_count += int(''.join(
            [str(relevant_numbers.index(op)) for op in output]))

        pass

    return total_count
예제 #25
0
def solve1(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None,
                        HOME_DIR))
    total_count = 0

    for line in lines:
        numbers: list
        output: list
        numbers, output = [[sorted(list(y)) for y in x.split(' ')]
                           for x in line.split(' | ')]
        numbers.sort(key=lambda num: len(num))

        relevant_numbers = [numbers[0], numbers[1], numbers[2],
                            numbers[9]]  # 1, 7, 4, 8

        total_count += len([op for op in output if op in relevant_numbers])

        pass

    return total_count
예제 #26
0
def solve2(is_sample=False):
    lines = list(get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None, HOME_DIR))
    crab_pos = [int(x) for x in lines[0].split(',')]

    all_pos = [x for x in range(max(crab_pos) + 1)]
    count_pos = [len([x for x in crab_pos if x == up]) for up in all_pos]
    cost_pos = []

    for to_pos in all_pos:
        current_cost = 0

        for from_index in range(len(all_pos)):
            from_pos, count = all_pos[from_index], count_pos[from_index]
            change_per_unit = abs(to_pos - from_pos)

            if change_per_unit:
                cost_per_unit = (change_per_unit * (change_per_unit + 1)) / 2
                current_cost += count * cost_per_unit

        cost_pos.append(current_cost)

    return min(cost_pos)
예제 #27
0
def solve1(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None,
                        HOME_DIR))
    coords = {'x': 0, 'y': 0}

    for line in lines:
        direction, units = line.split(' ')
        coord = 'x'
        is_addition = True

        if direction in y_moves:
            coord = 'y'
            if direction == y_moves[0]:
                is_addition = False

        if is_addition:
            coords[coord] += int(units)
        else:
            coords[coord] -= int(units)

    return coords['x'] * coords['y']
예제 #28
0
def solve1(is_sample=False):
    lines = list(get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None, HOME_DIR))
    value_per_digit = [0] * len(lines[0])
    count_digits = len(lines[0])
    threshold = len(lines) / 2
    gamma, epsilon = 0, 0

    factor = 2 ** (count_digits - 1)

    for line in lines:
        values = list(map(int, line))

        for i in range(0, count_digits):
            value_per_digit[i] += values[i]

    for digit in range(0, count_digits):
        if value_per_digit[digit] > threshold:
            gamma += factor
        else:
            epsilon += factor

        factor /= 2

    return gamma * epsilon
예제 #29
0
def solve2(is_sample=False):
    lines = list(
        get_input_lines(FILE_NUM, SAMPLES_FOLDER if is_sample else None,
                        HOME_DIR))
    fishes = [int(x) for x in lines[0].split(',')]
    fish_counts = get_fish_counts(fishes)
    pending_new_fish = 0

    for step in range(256):
        for count_index in range(len(fish_counts)):
            if count_index == 0:
                pending_new_fish = fish_counts[count_index]
            else:
                fish_counts[count_index - 1] = fish_counts[count_index]

            fish_counts[count_index] = 0

        # moving the old fish and new fish to their new positions
        if pending_new_fish:
            fish_counts[6] += pending_new_fish
            fish_counts[8] += pending_new_fish
            pending_new_fish = 0

    return sum(fish_counts)
예제 #30
0
def solve1():
    numbers = list(map(int, get_input_lines(FILE_NUM)))

    return find_invalid_number(numbers)