def part1(path): file_data = read_file(path or PATH, return_type=str, strip=True) grid = [] for point in file_data: if point == "": break x, y = point.split(",") grid = add_point(int(x), int(y), grid) folds = [] f = False for fold in file_data: if f: folds.append(fold.split(' ')[2]) if fold == "": f = True for fold in folds: [dir, line] = fold.split('=') if (dir == "y"): grid = fold_y(grid, int(line)) if (dir == "x"): grid = fold_x(grid, int(line)) break count = 0 for row, _ in enumerate(grid): for col, _ in enumerate(grid[row]): if grid[row][col] == ".": count += 1 return count
def part2(path): numbers = read_file(path or PATH, return_type=int, strip=True, split=",")[0] num_turns = 30000000 # A "memory" to store the past idices of values for quick lookup last_occurance = [0] * num_turns # Take the first few turns for turn, num in enumerate(numbers[:-1], 1): last_occurance[num] = turn last_num = numbers[-1] # interate through all the pages for turn_number in range(len(numbers), num_turns): # last time the number was said last_seen = last_occurance[last_num] # Distance from current number said num_age = turn_number - last_seen # First time number has been said if num_age == turn_number: num_age = 0 # load current number into memory last_occurance[last_num] = turn_number last_num = num_age print(num_age)
def part_2(path): global centre_of_mass,count orbits = read_file(path or PATH, return_type=str,strip=True, split=")") # Due to the randomness of the data, iterate through # each pair searching for a node that fits into the tree, # then remove that pair from the data. Quit when all nodes # have been added to the tree while len(orbits) > 0: for i in range(len(orbits)): if make_tree(orbits[i]): orbits.remove(orbits[i]) break # Find the pathways to two leaf nodes you_path = find_node_trail(centre_of_mass,"YOU") san_path = find_node_trail(centre_of_mass,"SAN") # print(you_path) # print(san_path) # Find a the first matching OrbitNode between the two leaf node pathways for node in you_path: if node in san_path: distance = san_path.index(node)-1 + you_path.index(node)-1 break print("The minimum number of orbital transfers required between YOU and SAN is %d" % distance)
def part_1(path): global IMAGE_WIDTH, IMAGE_HEIGHT image = read_file(path or PATH, return_type=str, strip=True)[0] image_size = len(image) image_ptr = 0 smallest_zeros = -1 total = 0 while image_ptr < image_size: layer = 0 num_zeros = 0 num_ones = 0 num_twos = 0 for idx in range(IMAGE_WIDTH): for jdx in range(IMAGE_HEIGHT): if image[image_ptr] == "0": num_zeros += 1 elif image[image_ptr] == "1": num_ones += 1 elif image[image_ptr] == "2": num_twos += 1 image_ptr += 1 layer += 1 if num_zeros < smallest_zeros or smallest_zeros == -1: smallest_zeros = num_zeros total = num_ones * num_twos print("The layer with the least 0s totalled %d (1's * 2's)" % (total))
def part2(path): file_data = read_file(path or PATH, return_type=str, strip=True) grid = [] for point in file_data: if point == "": break x, y = point.split(",") grid = add_point(int(x), int(y), grid) folds = [] f = False for fold in file_data: if f: folds.append(fold.split(' ')[2]) if fold == "": f = True for fold in folds: [dir, line] = fold.split('=') if (dir == "y"): grid = fold_y(grid, int(line)) if (dir == "x"): grid = fold_x(grid, int(line)) display_grid(grid)
def part1(path): shopping_list = read_file(path or PATH,return_type=str,strip=True) dish_list = [] alergens = [] ingredients = [] for food in shopping_list: (dish_ingredients,dish_alergens) = food.split("(") dish_ingredients = dish_ingredients.split(" ")[:-1] dish_alergens = dish_alergens.split(")")[0].split(" ")[1:] for alergen in dish_alergens: if alergen not in alergens: alergens.append(alergen) for ingredient in dish_ingredients: if ingredient not in ingredients: ingredients.append(ingredient) dish_list.append(Dish(dish_ingredients,dish_alergens)) print(alergens) print(ingredients) for dish in dish_list: print(dish)
def part_2(path): global numSteps wires = read_file(path or PATH, return_type=str, strip=True, split=",") polar_wires = [] for wire in wires: polar_wire = [[0, 0, 0]] numSteps = 0 for direction in wire: to_polar(polar_wire, direction) polar_wires.append(polar_wire) # sort the wires by Y then X values to derive an always incrementing pattern for wire in polar_wires: wire.sort(key=itemgetter(Y)) wire.sort(key=itemgetter(X)) matching_points = getMatchingPoints(polar_wires) # Iterate through the matching points to calculate the smallest number of steps smallest_steps = 0 for point in matching_points: curr_steps = point[2] + point[3] if curr_steps < smallest_steps or smallest_steps == 0: smallest_steps = curr_steps print( "The fewest combined steps the wires must take to reach an intersection is %d" % smallest_steps) pass
def part_2(path): # Colect the weights of the modules module_weights = read_file(path or PATH, return_type=int, strip=True) """ Desc: A recursive function used to calculate the weight of modules, then the weight of that added fuel and so on until reaching the "Wishing really hard" cutoff Param: weight: int of the weight to calculate fuel cost for """ def fuel_cost(weight): curr_weight = 0 curr_cost = floor(weight / 3) - 2 # Wishing really hard cutoff if (curr_cost >= 0): # Add the current fuel weight to the total curr_weight += curr_cost # Calculate the next weight from the newly added fuel curr_weight += fuel_cost(curr_cost) return curr_weight return 0 # Build an array of each modules total fuel costs fuel_cost = [fuel_cost(weight) for weight in module_weights] # Provide the summation as the solution print( "The sum of the complete fuel requirements for all of the modules is %d" % sum(fuel_cost))
def part_2(path): opcodes = read_file(path or PATH,return_type=int,strip=True,split=",") highest_output = 0 best_phase = [] generation = 0 for code in opcodes: for phase_setting in list(permutations([5,6,7,8,9])): prev_input = 0 last_amplifier = 0 opcode_phase = [code.copy(),code.copy(),code.copy(),code.copy(),code.copy()] while prev_input != -1: amplifier = generation % 5 prev_input = comput_opcode(opcode_phase[amplifier],phase_setting[amplifier],prev_input) print(prev_input, generation) print(opcode_phase) input() # print(amplifier,prev_input,generation) if amplifier == 4: last_amplifier = prev_input generation+=1 # print(phase_setting, last_amplifier) if last_amplifier > highest_output: highest_output = last_amplifier
def part_1(path): # collect list of opcodes from the datafile opcodes = read_file(path or PATH, return_type=int, strip=True, split=",") # iterate through each opcode for opcode in opcodes: # initiate with pre "1202 program alarm" state opcode[1] = 12 opcode[2] = 2 # skip 4 to reach next instruction for i in range(0, len(opcode), 4): if opcode[i] == 99: break # param 1 (i+1) as index for a # param2 (i+2) as index for b # param3 (i+3) as index for c # addition opcode, c = a + b if opcode[i] == 1: opcode[opcode[i + 3]] = opcode[opcode[i + 1]] + opcode[opcode[i + 2]] # multiplication opcode, c = a * b elif opcode[i] == 2: opcode[opcode[i + 3]] = opcode[opcode[i + 1]] * opcode[opcode[i + 2]] print("Value left at address 0: %d" % opcode[0])
def part_1(path): wires = read_file(path or PATH, return_type=str, strip=True, split=",") polar_wires = [] for wire in wires: polar_wire = [[0, 0, 0]] for direction in wire: to_polar(polar_wire, direction) polar_wires.append(polar_wire) # sort the wires by Y then X values to derive an always incrementing pattern for wire in polar_wires: wire.sort(key=itemgetter(Y)) wire.sort(key=itemgetter(X)) matching_points = getMatchingPoints(polar_wires) # Iterate through the matching points to calculate the smallest distance smallest_manhatten = 0 for point in matching_points: curr_manhatten = abs(point[X]) + abs(point[Y]) if curr_manhatten < smallest_manhatten or smallest_manhatten == 0: smallest_manhatten = curr_manhatten print( "The Manhattan distance from the central port to the closest intersection is %d" % smallest_manhatten)
def part1(path): ticket_specs = read_file(path or PATH, return_type=str, strip=True) validator = Ticket_validator() i = 0 while (ticket_specs[i] != ""): validator.parse_rules(ticket_specs[i]) i += 1 i += 2 my_ticket = ticket_specs[i] i += 3 sum = 0 while (i < len(ticket_specs)): for val in ticket_specs[i].split(","): try: val = int(val) except ValueError: print("Something wrong with a ticket, val is not an int") sys.exit() if (not validator.within_rules(val)): sum += val i += 1 print(sum)
def part1(path): inputs = read_file(path or PATH, return_type=str, strip=True) most_common = [] for bit in inputs[0]: most_common.append({ '0': 0, '1': 0, }) for input in inputs: for i in range(len(input)): most_common[i][input[i]] += 1 gamma_bin = [] epsilon_bin = [] for common in most_common: if common['0'] > common['1']: gamma_bin.append('0') epsilon_bin.append('1') else: gamma_bin.append('1') epsilon_bin.append('0') gamma_dec = int("".join(gamma_bin), 2) epsilon_dec = int("".join(epsilon_bin), 2) print(gamma_dec * epsilon_dec)
def part1(path): boarding_passes = read_file(path or PATH, return_type=str, strip=True) _ids = [] for boarding_pass in boarding_passes: _ids.append(retrieve_id(boarding_pass)) print(max(_ids))
def part_1(path): # Colect the weights of the modules module_weights = read_file(path or PATH, return_type=int, strip=True) # Calculate the fuel cost for each module fuel_cost = [floor(weight / 3) - 2 for weight in module_weights] # Provide the summation as the solution print("The sum of the fuel requirements for all of the modules is %d" % sum(fuel_cost))
def part2(path): budget_report = read_file(path or PATH,return_type=int,strip=True) budget_report.sort() # print(budget_report) (i,j,k) = find_triplet(budget_report, MATCH_NUMBER) print(i,j,k,i+j+k,i*j*k) pass
def part2(path): luggage_rules = read_file(path or PATH, return_type=str, strip=True) rules = {} for rule in luggage_rules: (parent, children) = define_rule(rule) rules[parent] = children print(count_inner_bags(rules, "shiny gold") - 1)
def part1(path): budget_report = read_file(path or PATH,return_type=int,strip=True) budget_report.sort() # print(budget_report) (i,j) = find_pair(budget_report,MATCH_NUMBER) print(i,j,i*j) pass
def part2(path): passwords = read_file(path or PATH, return_type=str, strip=True) count = 0 for password in passwords: spec = parse_password(password) if (valid_password_xor(spec)): count += 1 print(count)
def part1(path): tree_rows = read_file(path or PATH, return_type=str, strip=True) position = [0, 0] max_width = len(tree_rows[0]) - 1 max_height = len(tree_rows) - 1 slope = [1, 3] tree_count = walk_slope(tree_rows, position, slope, max_height, max_width) print(tree_count)
def part1(path): equations = read_file(path or PATH,return_type=str,strip=True) sum = 0 for equation in equations: equation = Equation(equation) equation.evaluate() # print(equation) sum += equation.answer print(sum)
def part1(path): file_passports = read_file(path or PATH,return_type=str,strip=True) passports = collect_passports(file_passports) valid_count = 0 for passport in passports: if (passport.is_valid()): valid_count += 1 print(valid_count)
def part1(path): depths = read_file(path or PATH, return_type=int, strip=True) num_increases = 0 last_depth = depths[0] for i in range(1,len(depths)): if (depths[i] > last_depth): num_increases += 1 last_depth = depths[i] print(f"Number of increases {num_increases}")
def part2(path): port_output = read_file(path or PATH,return_type=int,strip=True) weakness_sum = find_invalid_number(port_output) if (len(weakness_sum) > 1): print("Something has gone wrong") sys.exit() weakness_sum = weakness_sum[0] contiguous_list = contiguous_sum(port_output,weakness_sum) print(min(contiguous_list) + max(contiguous_list))
def part2(path): file_data = read_file(path or PATH, return_type=str, strip=True) caves = build_map(file_data) # for cave in caves: # print(cave, caves[cave]) find_path_part_2(caves, 'start', ['start'], 0) # for path in CAVE_PATHS: # print(path) return len(CAVE_PATHS)
def part1(path): file_data = read_file(path or PATH, return_type=str, strip=True) fishes = [Fish(int(fish)) for fish in file_data[0].split(',')] for _ in range(80): for fish in fishes: did_cycle = fish.grow() if (did_cycle): fishes.append(Fish(9)) return (len(fishes))
def part1(path): file_data = read_file(path or PATH, return_type=str, strip=True) octopi = build_matrix(file_data) steps = 100 total_flashes = 0 for _ in range(steps): octopi = charge(octopi) octopi = flash(octopi) (octopi, flashes) = count(octopi) total_flashes += flashes return total_flashes
def part2(path): boarding_passes = read_file(path or PATH, return_type=str, strip=True) _ids = [] for boarding_pass in boarding_passes: _ids.append(retrieve_id(boarding_pass)) lower_bound = min(_ids) upper_bound = max(_ids) my_seat = sum(list(range(lower_bound, upper_bound + 1))) - sum(_ids) print(my_seat)
def part1(path): file_data = read_file(path or PATH, return_type=str, strip=True) template, replacements = get_input(file_data) for _ in range(10): template = make_replacements(template, replacements) counts = defaultdict(int) for el in template: counts[el] += 1 return max(counts.values()) - min(counts.values())
def part_2(path): # collect list of opcodes from the datafile opcodes = read_file(path or PATH, return_type=int, strip=True, split=",") """ Desc: Initiate the opcode with the noun and verb, and execute the adjusted opcode returning the value in address 0 Param: opcode: list of ints used to simulate an Intcode computer, noun: int to initiate address[1] verb: int to initiate address[2] """ def comput_opcode(opcode=None, noun=0, verb=0): if not opcode: print("Please provide an opcode for computation") exit(0) # Initiate opcode opcode[1], opcode[2] = noun, verb # skip 4 to reach next instruction for i in range(0, len(opcode), 4): if opcode[i] == 99: break # param 1 (i+1) as index for a # param2 (i+2) as index for b # param3 (i+3) as index for c # addition opcode, c = a + b if opcode[i] == 1: opcode[opcode[i + 3]] = opcode[opcode[i + 1]] + opcode[opcode[i + 2]] # addition opcode, c = a * b elif opcode[i] == 2: opcode[opcode[i + 3]] = opcode[opcode[i + 1]] * opcode[opcode[i + 2]] return opcode[0] # iterate through each opcode for opcode in opcodes: max_val = len(opcode) - 1 # Check all combinations of nouns and verbs from 0 - 99 for noun in range(100): for verb in range(100): # check for overflow if noun > max_val or verb > max_val: continue # compute the opcode with the current combination of noun, verb address_0 = comput_opcode(opcode.copy(), noun, verb) if (address_0 == 19690720): print("Noun: %d, Verb: %d" % (noun, verb)) print("What is 100 * noun + verb = %d" % (100 * noun + verb))