Exemplo n.º 1
0
                    valid_positions.remove(position)

        field_valid_positions[field] = valid_positions

    for field, valid_positions in sorted(field_valid_positions.items(),
                                         key=lambda x: len(x[1])):

        for position in valid_positions:
            if position not in field_positions.values():
                field_positions[field] = position
                break

    return field_positions


def check_departure_fields(field_map, ticket):
    return reduce(
        mul,
        (ticket[pos]
         for fld, pos in field_map.items() if fld.startswith("departure")))


rules, own_ticket, nearby_tickets = parse_ticket_data(load_input("day16.txt"))

nearby_valid_tickets, invalid_fieldsum = validate_tickets(
    rules.values(), nearby_tickets)
print(f"Part 1 => {invalid_fieldsum}")

fld_positions = resolve_field_positions(rules, nearby_valid_tickets)
print(f"Part 2 => {check_departure_fields(fld_positions, own_ticket)}")
Exemplo n.º 2
0
    else:
        next_cup[initial_cup_sequence[-1]] = curr_cup

    for _ in range(iterations):

        # Cut next 3 cups
        move_cups = get_next_elements(next_cup, curr_cup, 3)
        next_cup[curr_cup] = next_cup[move_cups[-1]]

        destination = curr_cup
        while destination in [curr_cup] + move_cups:
            destination -= 1
            if destination == 0:
                destination = max_cup

        # Insert cut cups after destination
        next_cup[move_cups[-1]] = next_cup[destination]
        next_cup[destination] = move_cups[0]

        curr_cup = next_cup[curr_cup]

    return get_next_elements(next_cup, 1, result_cups)


initial_cups = [int(c) for c in load_input("day23.txt")]

print(
    f"Part 1 => {''.join(str(c) for c in play_crab_cups(initial_cups, 100, 9, 8))}"
)
print(f"Part 2 => {product(play_crab_cups(initial_cups, 10**7, 10**6, 2))}")
Exemplo n.º 3
0
    while len(player1) > 0 and len(player2) > 0:

        snapshot = (tuple(player1), tuple(player2))
        if snapshot in previous_decks:
            # Player 1 instantly wins
            return 1, compute_score(player1)
        previous_decks.add(snapshot)

        c1, c2 = player1.pop(0), player2.pop(0)

        if c1 <= len(player1) and c2 <= len(player2):
            # Recurse
            sub_winner, _ = play_recursive_combat(player1[:c1], player2[:c2])
            if sub_winner == 1:
                player1 += [c1, c2]
            else:
                player2 += [c2, c1]
        else:
            play_hand(player1, player2, c1, c2)

    if len(player1) > 0:
        return 1, compute_score(player1)

    return 2, compute_score(player2)

deck1, deck2 = parse_decks(load_input("day22.txt"))

print(f"Part 1 => {play_combat(deck1, deck2)[1]}")
print(f"Part 2 => {play_recursive_combat(deck1, deck2)[1]}")
Exemplo n.º 4
0
    return matches

def count_sea_monsters(image):

    for o in orientations(image):
        monster_count = len(search_in_image(o, SEA_MONSTER))
        if monster_count > 0:
            return monster_count

    return 0

def water_roughness(image):
    return sum(row.count('#') for row in image) - count_sea_monsters(image) * sum(row.count('#') for row in SEA_MONSTER)


tiles = parse_tiles(load_input("day20.txt"))
corners = find_corner_tiles(tiles)

print(f"Part 1 => {product(corners)}")

nwc_tile = find_nw_corner(tiles)
recovered_image = complete_image(tiles, nwc_tile)

SEA_MONSTER = (
    "                  # ",
    "#    ##    ##    ###",
    " #  #  #  #  #  #   "
)

print(f"Part 2 => {water_roughness(recovered_image)}")
Exemplo n.º 5
0
        m = self._pattern.match(data)

        if m:
            quant = m.group(1)
            units = m.group(2)

            if units == "cm":
                return self._cm_validator.valid(quant)

            if units == "in":
                return self._in_validator.valid(quant)

        return False

input_data = load_input("day4.txt").split('\n\n')

validators = {
    'byr': BoundedIntValidator(1920, 2002),
    'iyr': BoundedIntValidator(2010, 2020),
    'ecl': ValueListValidator(['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']),
    'eyr': BoundedIntValidator(2020, 2030),
    'hcl': SimpleRegexValidator("^#[0-9a-f]{6}$"),
    'hgt': HeightValidator(),
    'pid': SimpleRegexValidator("^[0-9]{9}$")
}

all_fields_present = 0
all_fields_valid   = 0

for passport in input_data:
Exemplo n.º 6
0
    for alt in all_rules[rule_id].split('|'):
        alt_body = ""
        for add in alt.strip().split(' '):
            add_body = add.strip('"')
            if add_body in ('a', 'b'):
                alt_body += add_body
            else:
                alt_body += resolve_rule(all_rules, int(add_body), custom_rules)
        alterns.append(alt_body)

    if len(alterns) == 1:
        return alterns[0]

    return '(' + '|'.join(alterns) + ')'

rules, messages = parse_input_data(load_input("day19.txt"))

pattern = re.compile("^" + resolve_rule(rules, 0) + "$")
print(f"Part 1 => {sum(1 for msg in messages if pattern.match(msg))}")

special_cases = {
    8  : resolve_rule(rules, 42) + '+',
    11 : '(' + '|'.join(
            resolve_rule(rules, 42)
            + '{' + str(i) + '}'
            + resolve_rule(rules, 31)
            + '{' + str(i) + '}'
            for i in range(1, 6)
        ) + ')'
}
Exemplo n.º 7
0
from tools.general import load_input


def play_until(start_sequence, n_turns):

    last_term = start_sequence[-1]
    last_seen = {n: i for i, n in enumerate(start_sequence[:-1])}

    for turn in range(len(start_sequence) - 1, n_turns - 1):
        next_term = turn - last_seen.get(last_term,
                                         turn)  # zero if not seen before
        last_seen[last_term] = turn
        last_term = next_term

    return last_term


starting_numbers = [int(i) for i in load_input("day15.txt").split(',')]

print(f"Part 1 => {play_until(starting_numbers, 2020)}")
print(f"Part 2 => {play_until(starting_numbers, 30000000)}")
Exemplo n.º 8
0
from tools.general import load_input

sum_any = 0
sum_all = 0

for group in load_input("day6.txt").split("\n\n"):

    members = [set(i) for i in group.split('\n')]
    sum_any += len(set.union(*members))
    sum_all += len(set.intersection(*members))

print(f"Part 1 => {sum_any}")
print(f"Part 2 => {sum_all}")