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)}")
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))}")
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]}")
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)}")
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:
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) ) + ')' }
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)}")
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}")