def check_allergens(): recipy_list = util.parse_file_as_list(ingredients_file) ingredients_allergens_split = [ recipy.split(' (contains ') for recipy in recipy_list ] allergens_ingredients_sets = [[ set(row[1].replace(')', '').split(', ')), set(row[0].split(' ')) ] for row in ingredients_allergens_split] # map allergen to each set it is named in allergen_ingredients_dict = {} all_ingredients_set = set() combined_recipe_list = [] for allergen_set, ingredient_set in allergens_ingredients_sets: for allergen in allergen_set: if allergen not in allergen_ingredients_dict: allergen_ingredients_dict[allergen] = [] allergen_ingredients_dict[allergen].append(ingredient_set) all_ingredients_set |= ingredient_set combined_recipe_list.extend(list(ingredient_set)) # check which allergens intersect only on one ingredient in their sets determined_allergen_ingredient_dict = {} all_allergens_set = set(allergen_ingredients_dict.keys()) while len(all_allergens_set) > 0: for allergen, recipes in allergen_ingredients_dict.items(): # skip ingredients already found if allergen not in determined_allergen_ingredient_dict: # remove found allergens from intersection intersection = set.intersection(*recipes).difference( set(determined_allergen_ingredient_dict.values())) if len(intersection) == 1: determined_allergen_ingredient_dict[ allergen] = intersection.pop() all_allergens_set.remove(allergen) # count occurrences of non-allergen ingredients safe_ingredients_set = all_ingredients_set.difference( set(determined_allergen_ingredient_dict.values())) ingredient_counts = [ combined_recipe_list.count(ingredient) for ingredient in safe_ingredients_set ] print(determined_allergen_ingredient_dict) print(sum(ingredient_counts)) danger_list = list(determined_allergen_ingredient_dict.keys()) danger_list.sort() poison_string = '' for danger in danger_list: poison_string += determined_allergen_ingredient_dict.get(danger) + ',' print(poison_string)
def check_passwords(): password_file_list = util.parse_file_as_list(file=password_file) policy_password_lists = [line.split(':') for line in password_file_list] correct_password_count = 0 for policy, password in policy_password_lists: num_range, char = policy.split(' ') min_count, max_count = num_range.split('-') if int(min_count) <= password.count(char) <= int(max_count): correct_password_count += 1 print(correct_password_count)
def flip_it(): string_list = util.parse_file_as_list(real_file) the_grid = Grid() for direction_string in string_list: the_grid.parse_direction_string(direction_string) the_grid.goto_start() the_grid.print_hexagons() for x in range(100): the_grid.daily_flip() the_grid.print_hexagons()
def battle(): parsed_file = util.parse_file_as_list(decks) player_1_deck = [int(value) for value in parsed_file[1:26]] player_2_deck = [int(value) for value in parsed_file[28:]] winner = play_recursive_game(player_1_deck, player_2_deck) score = 0 if winner == 1: score = calculate_score(player_1_deck) elif winner == 2: score = calculate_score(player_2_deck) return score
def parse_seat_ids(): seats_lists = [ line.translate(str.maketrans({ 'F': '0', 'L': '0', 'B': '1', 'R': '1' })) for line in util.parse_file_as_list(seats_file) ] seat_ids = [int(x, 2) for x in seats_lists] my_seat = set(range(80, int('1' * 10, 2))) - set(seat_ids) print(max(seat_ids)) print(min(my_seat))
def check_passwords_part_2(): password_file_list = util.parse_file_as_list(file=password_file) policy_password_lists = [line.split(':') for line in password_file_list] correct_password_count = 0 for policy, password in policy_password_lists: password = password.strip() num_range, char = policy.split(' ') char_index_1, char_index_2 = num_range.split('-') a = password[int(char_index_1) - 1] b = password[int(char_index_2) - 1] if (a == char and b != char) or (b == char and a != char): correct_password_count += 1 print(correct_password_count)
def sort_adapters(): adapter_list = [int(num) for num in util.parse_file_as_list(adapter_file)] adapter_list.append(0) adapter_list.append(max(adapter_list) + 3) adapter_list.sort(reverse=True) jolt_diffs = [ adapter_list[index - 1] - adapter for index, adapter in enumerate(adapter_list) if index > 0 ] three_indices = [index for index, num in enumerate(jolt_diffs) if num == 3] three_indices.append(len(jolt_diffs)) three_index_diffs = [ x - three_indices[index - 1] for index, x in enumerate(three_indices) if index > 0 ] combination_dict = {5: 7, 4: 4, 3: 2, 2: 1, 1: 1} total_combinations = reduce( mul, [combination_dict.get(num) for num in three_index_diffs]) return jolt_diffs.count(1), jolt_diffs.count(3), total_combinations
import util import re homework = util.parse_file_as_list('input_files/day_18.txt') def alternate_math(): prepped_homework = [line.replace('))', ') )') for line in homework] return sum( [walk_the_line(line.split(' '), 0)[0] for line in prepped_homework]) def walk_the_line(operator_list, total_value, index=0): operator = '' while index < len(operator_list): value = operator_list[index] if value.isdigit() and total_value == 0: total_value = int(value) elif value.isdigit(): total_value = eval(str(total_value) + operator + value) elif value in ('+', '*'): operator = value elif value.startswith('('): operator_list[index] = value[1:] sub_total, end_index = walk_the_line(operator_list, 0, index=index) operator_list[index + 1:end_index] = [str(sub_total)] elif value.endswith(')'): if value != ')': total_value = eval( str(total_value) + operator + value.strip(')')) return total_value, index + 1
import itertools import util program_file = util.parse_file_as_list('input_files/day_14.txt') mem = {} def read_program(): bitmask = '' for line in program_file: if line.startswith('mask'): bitmask = line.lstrip('mask = ') elif line.startswith('mem'): address, value = line.split('] = ') mem_index = int(address.lstrip('mem[')) # bin_value, original_bin_length = format_value(value, mem_index) bin_value = format(int(mem_index), 'b').zfill(36) mask_decode(bin_value, bitmask, value) # masked_bin_value = apply_mask(bin_value, bitmask) # mem[mem_index] = masked_bin_value return sum([int(value) for value in mem.values()]) def format_value(bin_value, mem_index): bin_value = format(int(bin_value), 'b') original_bin_length = len(bin_value) if len(bin_value) < 36 - mem_index: needed_pad = 36 - mem_index - len(bin_value) bin_value = bin_value.rjust(needed_pad, '0') bin_value = bin_value.zfill(36) return bin_value, original_bin_length
import util movement_list = util.parse_file_as_list('input_files/day_12.txt') class Ship: def __init__(self, directions=movement_list): self.directions = [(direction[0], int(direction[1:])) for direction in directions] self.position = {'N': 0, 'S': 0, 'E': 0, 'W': 0} self.coordinates = {'W': 0, 'N': 0} self.waypoint_position = {'N': 1, 'S': 0, 'E': 10, 'W': 0} self.waypoint_coordinates = {'E': 10, 'N': 1} self.wind_direction_dict = {0: 'N', 90: 'E', 180: 'S', 270: 'W'} self.heading = 90 # initial heading is east def set_sail(self): # just follow the map without thinking for action, value in self.directions: if action in self.position.keys(): self.position[action] += value elif action == 'R': self.heading = (self.heading + value) % 360 elif action == 'L': self.heading = (self.heading - value) % 360 elif action == 'F': self.position[self.wind_direction_dict.get( self.heading)] += value print('Our current Manhatten position is: ' + str(abs(self.position.get('N') - self.position.get('S'))) + ', ' + str(abs(self.position.get('W') - self.position.get('E'))))
import util from itertools import product, starmap, combinations_with_replacement, accumulate number_file = 'input_files/day_9.txt' number_list = [int(num) for num in util.parse_file_as_list(number_file)] def find_weakness(preamble=25): for index, num in enumerate(number_list): if index > preamble - 1: all_possible_permutations = { x + y for x in number_list[index - preamble:] for y in number_list[index - preamble:] } if num not in all_possible_permutations: return num def determine_weakness(weak_num): combination_size = 2 while True: for index, value in enumerate(number_list, combination_size): if sum(number_list[index - combination_size:index]) == weak_num: return min(number_list[index - combination_size:index]) + max( number_list[index - combination_size:index]) index += 1 combination_size += 1
arrival station: 47-269 or 282-949 arrival platform: 26-500 or 521-960 arrival track: 26-681 or 703-953 class: 49-293 or 318-956 duration: 25-861 or 873-973 price: 30-446 or 465-958 route: 50-525 or 551-973 row: 39-129 or 141-972 seat: 37-566 or 573-953 train: 43-330 or 356-969 type: 32-770 or 792-955 wagon: 47-435 or 446-961 zone: 30-155 or 179-957 ''' nearby_tickets = util.parse_file_as_list('input_files/day_16.txt') your_ticket = [ '71', '127', '181', '179', '113', '109', '79', '151', '97', '107', '53', '193', '73', '83', '191', '101', '89', '149', '103', '197' ] def get_rules(): validation_dict = {} for rule in validation_rules.splitlines(): rule_name, values = rule.split(':') range_values = [ number.strip() for value in values.split(' or ') for number in value.split('-') ] validation_code_string = 'x in range({0}, {1} + 1) or x in range({2}, {3} + 1)'.format(
def tassies(): bag_rules = [rule.replace('bags', '').replace('bag', '') for rule in util.parse_file_as_list(bag_file)] return {pappies.strip(): {kiddo[3:].strip(): kiddo[1] for kiddo in kiddies.split(',')} for pappies, kiddies in [rule.strip('.').split('contain') for rule in bag_rules]}
import util import numpy seat_file = 'input_files/day_11.txt' seat_list = util.parse_file_as_list(seat_file) def seat_the_people(seat_list=seat_list, max_occupied=5, distance=int(10e12)): seat_map = {(x, y): char for y, line in enumerate(seat_list) for x, char in enumerate(line)} the_matrix = numpy.array([list(line) for line in seat_list]) still_movin_around = True while still_movin_around: still_movin_around = False locations_to_change = {} for location, char in seat_map.items(): if char != '.': coords_to_check = check_matrix(the_matrix, location[0], location[1], distance) if coords_to_check.count('#') >= max_occupied and char == '#': locations_to_change[location] = 'L' elif coords_to_check.count('#') == 0 and char == 'L': locations_to_change[location] = '#' if len(locations_to_change) > 0: still_movin_around = True for loc, new_value in locations_to_change.items(): seat_map[loc] = new_value the_matrix[loc[1]][loc[0]] = new_value return sum([1 for hekje in seat_map.values() if hekje == '#'])
def read_instructions(self, file): return [ self.Instruction(operation=instruction.split(' ')[0], value=instruction.split(' ')[1]) for instruction in util.parse_file_as_list(file) ]
import util import math raw_schedule = util.parse_file_as_list('input_files/day_13.txt') def check_schedule(): departure_time = int(raw_schedule[0]) bus_ids = [ int(bus_id) for bus_id in raw_schedule[1].split(',') if bus_id != 'x' ] bus_wait_times = {} for bus_id in bus_ids: wait_time = bus_id - (departure_time % bus_id) bus_wait_times[bus_id] = wait_time return bus_wait_times def diff_approach(): bus_id_time_offset_dict = { int(bus_id): time_offset for time_offset, bus_id in enumerate(raw_schedule[1].split(',')) if bus_id != 'x' } bus_ids = [bus_id for bus_id in bus_id_time_offset_dict.keys()] bus_ids.sort() common_denom = bus_ids[0] first_occ = 0 for index, bus_id in enumerate(bus_ids): if index > 0: this_buss_offset = bus_id_time_offset_dict.get(bus_id)
import util import re test_rules = [ '0: 4 1 5', '1: 2 3 | 3 2', '2: 4 4 | 5 5', '3: 4 5 | 5 4', '4: "a"', '5: "b"', '', 'ababbb', 'bababa', 'abbbab', 'aaabbb', 'aaaabbb' ] twest_rules = util.parse_file_as_list('input_files/day_19_part_2.txt') the_rules = util.parse_file_as_list('input_files/day_19.txt') class Node: def __init__(self, left=None, right=None): self.left = left self.right = right self.value = None self.parent = None self.str_list = [] self.end_nodes = [] def __repr__(self): return 'Node value: ' + str(self.value) def add_child(self, value=None, go_right=False): child = Node() child.parent = self child.value = value if go_right:
import util tree_file = 'input_files/day_3.txt' tree_file_list = util.parse_file_as_list(file=tree_file) test_map = [ '..##.......', '#...#...#..', '.#....#..#.', '..#.#...#.#', '.#...##..#.', '..#.##.....', '.#.#.#....#', '.#........#', '#.##...#...', '#...##....#', '.#..#...#.#' ] def count_trees_on_slope_part_1(right, down): return sum([ 1 for index, line in enumerate(tree_file_list) if index % down == 0 and line[round(((index * right) / down)) % len(line)] == '#' ]) def count_trees_on_slope_part_2(): input_array = [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)] print([ count_trees_on_slope_part_1(right, down) for right, down in input_array ])
import util import numpy as np import itertools test_dimension = ['.#.', '..#', '###'] start_dimension = util.parse_file_as_list('input_files/day_17.txt') def enter_the_matrix_again(dimensions=4): universe = np.array([[1 if char == '#' else 0 for char in line] for line in start_dimension], ndmin=dimensions) for loops in range(6): universe = another_dimension(universe) return universe.sum() def expand_the_universe(universe): # order of position in matrix is z, y, x z, y, x = universe.shape expanded_universe = np.array(np.zeros((z + 4, y + 4, x + 4))) expanded_universe[2:-2, 2:-2, 2:-2] = universe the_newlyverse = np.array(np.zeros((z + 4, y + 4, x + 4))) for cube_coords in itertools.product( range(1, z + 3), itertools.product(range(1, x + 3), repeat=2)): z, y_x = cube_coords y, x = y_x cube_value = expanded_universe[z, y, x]