def test_check_passphrase(): assert check_passphrase("aa bb cc dd ee") assert not check_passphrase("aa bb cc dd aa") assert check_passphrase("aa bb cc dd aaa") rows = data.split("\n") num = len([x for x in rows if check_passphrase(x)]) assert num == 451
def test_check_passphrase_two(): assert check_passphrase_two("abcde fghij") assert not check_passphrase_two("abcde xyz ecdab") assert check_passphrase_two("a ab abc abd abf abj") assert check_passphrase_two("iiii oiii ooii oooi oooo") assert not check_passphrase_two("oiii ioii iioi iiio") rows = data.split("\n") num = len([x for x in rows if check_passphrase_two(x)]) assert num == 223
f = rotations[((4 - int(val / 90)) % 4)] # modulo if L0 exists new_waypoint = f(waypoint) return pos, new_waypoint elif c == 'F': new_pos = (pos[0] + val * waypoint[0], pos[1] + val * waypoint[1]) return new_pos, waypoint else: dir = directions[c] new_waypoint = (waypoint[0] + val * dir[0], waypoint[1] + val * dir[1]) return pos, new_waypoint # part 1 curr_dir = 1 # east curr_pos = (0, 0) for l in data.split('\n'): curr_pos, curr_dir = parse_command(l, curr_pos, curr_dir) print(abs(curr_pos[0]) + abs(curr_pos[1])) # part 2 waypoint = (10, -1) pos = (0, 0) for l in data.split('\n'): pos, waypoint = parse_command_2(l, pos, waypoint) print(abs(pos[0]) + abs(pos[1]))
if precedence[c] < precedence[top]: break # if precedence is higher or the same output_queue.append(operator_stack.pop()) operator_stack.append(c) while operator_stack: output_queue.append(operator_stack.pop()) return ''.join(output_queue) from data import data expressions = data.split('\n') def remove_whitespace(s): return ''.join(s.split()) # part 1 precedence_1 = {'+': 1, '-': 1, '*': 1} print(sum(eval_rpn(to_rpn(remove_whitespace(e), precedence_1))[0] for e in expressions)) # part 2 precedence_2 = {'+': 1, '-': 1, '*': 2} print(sum(eval_rpn(to_rpn(remove_whitespace(e), precedence_2))[0] for e in expressions))
p_i = [j for j, node in enumerate(jolt_list[:i]) if n_i - node <= 3] paths.append(p_i) return paths def fast_count(paths): num_paths = [1] * len(paths) for i in range(1, len(paths)): p_i = paths[i] num_paths[i] = sum(num_paths[j] for j in p_i) return num_paths[-1] joltages = sorted(list(map(int, data.split('\n')))) joltages = [0, *joltages, max(joltages) + 3] # part 1 dj = np.diff(joltages) print(sum(dj == 1) * sum(dj == 3)) t0 = time.time() # part 2 paths = find_paths(joltages) print(fast_count(paths)) t1 = time.time() print("counted paths in {:0.0f} microseconds".format((t1 - t0) * 1e6))
from data import data import itertools items = data.split('\n\n') def count_answers(item): individual_answers = [list(ans) for ans in item.split('\n')] # flatten nested list all_answers = set(itertools.chain(*individual_answers)) return len(all_answers) print(sum([count_answers(item) for item in items])) def count_answers_2(item): individual_answers = [list(ans) for ans in item.split('\n')] # flatten nested list all_answers = set(itertools.chain(*individual_answers)) return sum([all(c in ia for ia in individual_answers) for c in all_answers]) print(sum([count_answers_2(item) for item in items]))
from data import data import re lines = data.split('\n') regex_mask = re.compile('mask = ([10X]+)') regex_assignment = re.compile('mem\[(\d+)\] = (\d+)') def parse_lines(lines): out = [] assignments = [] mask = "" for line in lines: m = regex_mask.match(line) if m: # append old out.append((mask, assignments)) # reset mask, = m.groups() assignments = [] else: m2 = regex_assignment.match(line) if m2: address, val = m2.groups() assignments.append((int(address), int(val))) # append last element
# from data import data import re def parse_line(line): ingredients, allergens = line.split(' (contains ') return set(ingredients.split(' ')), set(allergens[:-1].split(', ')) lines = [parse_line(line) for line in data.split('\n')] all_ingredients = { ingredient for ingredients, _ in lines for ingredient in ingredients } all_allergens = { allergens for _, allergens in lines for allergens in allergens } # find the sets of ingredients that always co-occur with each allergen candidate_dictionary = dict() for query_allergen in all_allergens: candidate_ingredients = all_ingredients.copy() for ingredients, allergens in lines: if query_allergen in allergens:
return all_suffixes def is_valid(match): if match: if match[0] == '': return True return False # to run part 1, change rule 8 and 11 in data from data import data, test_data rule_str, messages = data.split('\n\n') rule_dict = {id: matches for id, matches in (parse_rule(r) for r in rule_str.split('\n'))} import time rule = rule_dict[0] t0 = time.time() print(sum(is_valid(m) for m in (match(mess, rule, rule_dict) for mess in messages.split('\n')))) t1 = time.time() print(t1 - t0) # -------------- legacy code for part 1 --------------
def check_value(val, rules): return any(val in range(*r0) or val in range(*r1) for _, r0, r1 in rules) def error_rate(ticket, rules): invalid_values = (val for val in ticket if not check_value(val, rules)) return sum(invalid_values) def is_valid(ticket, rules): return all(check_value(val, rules) for val in ticket) # load data rules_str, my_ticket, nearby_tickets = data.split('\n\n') rules = parse_rules(rules_str) _, *ticket_strings = nearby_tickets.split('\n') tickets = [[int(n) for n in t] for t in (ts.split(',') for ts in ticket_strings)] _, my_ticket_str = my_ticket.split('\n') my_ticket_values = [int(s) for s in my_ticket_str.split(',')] # part 1 print(sum(error_rate(ticket, rules) for ticket in tickets)) # part 2
n_sea_monsters = 0 for i in range(h_im - h): for j in range(w_im - w): m_ij = im[i:i + h, j:j + w] * monster if sum(m_ij.ravel()) == len_monster: n_sea_monsters += 1 return n_sea_monsters # load data and build puzzle from data import data tiles = [parse_tile(s) for s in data.split('\n\n')] edge_dict = get_edge_dict(tiles) tile_dict = get_tile_dict(tiles) puzzle, puzzle_edges = build_jigsaw_puzzle(tile_dict, edge_dict) x_pos = [pos[0][0] for _, pos in puzzle.items()] y_pos = [pos[0][1] for _, pos in puzzle.items()] size = max(y_pos) - min(y_pos) + 1 grid = [[0] * size for _ in range(size)] for id, meta in puzzle.items(): x, y = meta[0] grid[x - min(x_pos)][y - min(y_pos)] = (id, meta[1])
from day05 import reach_exit, reach_exit_two from data import data target_list = [int(x) for x in data.split("\n")] def test_reach_exit(): assert reach_exit([0, 3, 0, 1, -3]) == 5 assert reach_exit(target_list) == 372139 def test_reach_exit_two(): assert reach_exit_two([0, 3, 0, 1, -3]) == 10 assert reach_exit_two(target_list) == 29629538
from data import data seat_IDs = data.split('\n') def row_num(seat_IDs): row_num = 0 for i in range(7): s_i = seat_IDs[i] b = 0 if s_i == 'F' else 1 row_num += 2**(6 - i) * b col_num = 0 for i in range(7, 10): s_i = seat_IDs[i] b = 0 if s_i == 'L' else 1 col_num += 2**(9 - i) * b return row_num, col_num IDs = sorted( [8 * r + c for r, c in (row_num(seat_ID) for seat_ID in seat_IDs)]) # part 1 print(max(IDs)) # part 2 for i in range(len(IDs) - 1): if IDs[i + 1] - IDs[i] > 1: print(IDs[i] + 1)
from data import data as raw_data import re data = raw_data.split('\n\n') required_fields = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid'] # part 1 def validate_entry(e): fields = re.findall(r"\w+(?=:)", e) for f in required_fields: if f not in fields: return False return True print(sum([validate_entry(d) for d in data])) # part 2 def validate_byr(s): return 1920 <= int(s) <= 2002 def validate_iyr(s): return 2010 <= int(s) <= 2020 def validate_eyr(s):
from data import data seats = data.split('\n') n_row = len(seats) n_col = len(seats[0]) # pad seats with floor seats = [['.', *s, '.'] for s in seats] seats = [['.'] * (n_col + 2), *seats, ['.'] * (n_col + 2)] neighbors = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)] def change_empty(old_seats, i, j): return not any(old_seats[i + di][j + dj] == '#' for dj, di in neighbors) def change_occupied(old_seats, i, j): return sum(old_seats[i + di][j + dj] == '#' for dj, di in neighbors) >= 4 def get_first(old_seats, i, j, direction): while (0 < i < n_row + 1) & (0 < j < n_col + 1): i += direction[0] j += direction[1] c = old_seats[i][j] if c != '.': return c