def test_second(self): batch2 = "".join(utils.parse_file_lines("day4_test_input2.txt", str)) + "\n" self.assertEqual(day4.find_valid_passports_2(batch2), 0) batch3 = "".join(utils.parse_file_lines("day4_test_input3.txt", str)) + "\n" self.assertEqual(day4.find_valid_passports_2(batch3), 4)
def test_second(self): instructions = utils.parse_file_lines("day12_test_input1.txt", str) self.assertEqual( day12.follow_instructions_waypoint(instructions, (0, 0), (10, 1)), 286)
def test_second(self): for num_str, expected in zip( utils.parse_file_lines("day15_test_input1.txt", str), [175594, 2578, 3544142, 261214, 6895259, 18, 362]): self.assertEqual( day15.play_game(num_str, 30000000), expected)
def test_first(self): for num_str, expected in zip( utils.parse_file_lines("day15_test_input1.txt", str), [436, 1, 10, 27, 78, 438, 1836]): self.assertEqual( day15.play_game(num_str, 2020), expected)
def test_first(self): spec = utils.parse_file_lines("day7_test_input1.txt", str) relationship_map = day7.parse_all_lines(spec) gold_parents = set() day7.find_parents(relationship_map, "shiny gold", gold_parents) self.assertEqual( gold_parents, {"bright white", "muted yellow", "dark orange", "light red"})
def test_second(self): nums = utils.parse_file_lines("day9_test_input1.txt", int) self.assertEqual(day9.find_range_sum(nums, 127), 62)
import utils def play_game(starting_num_str, iterations): starting_nums = [int(num) for num in starting_num_str.strip().split(",")] ages = {} last_spoken = None first_time = False diff = None for turn_idx in range(iterations): if turn_idx < len(starting_nums): last_spoken = starting_nums[turn_idx] elif first_time: last_spoken = 0 else: last_spoken = diff first_time = last_spoken not in ages.keys() if not first_time: diff = turn_idx - ages[last_spoken] ages[last_spoken] = turn_idx return last_spoken if __name__ == "__main__": input_nums = utils.parse_file_lines("day15_input.txt", str)[0] print("Part 1: {}".format(play_game(input_nums, 2020))) print("Part 2: {}".format(play_game(input_nums, 30000000)))
def test_second(self): program = utils.parse_file_lines("day8_test_input1.txt", str) program = [line.strip() for line in program] self.assertEqual(day8.change_code(program), 8)
def test_first(self): instructions = utils.parse_file_lines("day12_test_input1.txt", str) self.assertEqual( day12.follow_instructions_ship(instructions, 0, 0, "E"), 25)
if ((field_int not in possibility[1]) and (field_int not in possibility[2])): possibilities[field_idx].remove(possibility) possibilities = [{rule[0] for rule in possibility} for possibility in possibilities] while (sum([len(possibility_set) for possibility_set in possibilities]) > len(possibilities)): singletons = [] for idx, possibility_set in enumerate(possibilities): if len(possibility_set) == 1: singletons.append((idx, list(possibility_set)[0])) for singleton in singletons: for idx, possibility_set in enumerate(possibilities.copy()): if idx != singleton[0] and singleton[1] in possibilities[idx]: possibilities[idx].remove(singleton[1]) your_ticket = [int(num) for num in yours.split("\n")[1].strip().split(",")] return (your_ticket, [list(possibility)[0] for possibility in possibilities]) if __name__ == "__main__": input_spec = "".join(utils.parse_file_lines("day16_input.txt", str)) print("Part 1: {}".format(find_error_rate(input_spec))) your_tkt, field_names = identify_fields(input_spec) acc = 1 for idx, field in enumerate(field_names): if field.startswith("departure"): acc *= your_tkt[idx] print("Part 2: {}".format(acc))
return False else: return False except ValueError: print("Non-int hgt: {}".format(value)) return False elif name == "hcl": if re.fullmatch(r"#[a-f0-9]{6}", value) is None: print("Invalid hcl: {}".format(value)) return False elif name == "ecl": if value not in ("amb", "blu", "brn", "gry", "grn", "hzl", "oth"): print("Invalid ecl: {}".format(value)) return False elif name == "pid": if re.fullmatch(r"[0-9]{9}", value) is None: print("Invalid pid: {}".format(value)) return False elif name == "cid": continue else: print("Invalid key: {}".format(name)) return False return True if __name__ == "__main__": batch_input = "".join(utils.parse_file_lines("day4_input.txt", str)) + "\n" print("Part 1: {}".format(find_valid_passports(batch_input))) print("Part 2: {}".format(find_valid_passports_2(batch_input)))
def test_first(self): nums = utils.parse_file_lines("day1_test_input1.txt", int) self.assertEqual(day1.find_sum_2(nums, 2020), 514579)
def test_first(self): notes = utils.parse_file_lines("day13_test_input1.txt", str) self.assertEqual( day13.find_earliest_bus(notes), 295)
def test_second(self): notes = utils.parse_file_lines("day13_test_input1.txt", str) self.assertEqual( day13.find_bus_pattern(notes), 1068781)
import utils def find_earliest_bus(notes): earliest = int(notes[0]) buses = notes[1].strip().split(",") buses = [int(bus) for bus in buses if bus != "x"] wait_times = {bus: (bus - (earliest % bus)) % bus for bus in buses} shortest_wait = min(wait_times.items(), key=lambda x: x[1]) return shortest_wait[0] * shortest_wait[1] def find_bus_pattern(notes): buses = notes[1].strip().split(",") max_bus = max([int(bus) for bus in buses if bus != "x"]) max_idx = buses.index(str(max_bus)) num_conditions = sum([bus != "x" for bus in buses]) for candidate in count(max_bus, max_bus): candidate -= max_idx if (sum([(int(bus) - (candidate % int(bus))) % int(bus) == idx for idx, bus in enumerate(buses) if bus != "x"]) == num_conditions): return candidate if __name__ == "__main__": input_notes = utils.parse_file_lines("day13_input.txt", str) print("Part 1: {}".format(find_earliest_bus(input_notes))) print("Part 2: {}".format(find_bus_pattern(input_notes)))
all_ids = {find_id(seat) for seat in all_seats} for possible_id in range((127 * 8) + 7): if ((set([possible_id - 1, possible_id + 1]) <= all_ids) and possible_id not in all_ids): return possible_id raise ValueError() def find_id(seat): seat = seat.strip() row = traverse_binary_space(seat[:7], "F", "B", 0) col = traverse_binary_space(seat[7:], "L", "R", 0) return (row * 8) + col def traverse_binary_space(spec, lower_key, upper_key, lower): upper = lower + (2**len(spec)) - 1 for key in spec: stride = ((upper - lower) + 1) / 2 if key == lower_key: upper -= stride elif key == upper_key: lower += stride return lower if __name__ == "__main__": seat_input = utils.parse_file_lines("day5_input.txt", str) print("Part 1: {}".format(max([find_id(seat) for seat in seat_input]))) print("Part 2: {}".format(find_missing_seat(seat_input)))
parse_line(line.strip(), relationship_map) return relationship_map def parse_line(spec_string, relationship_map): content_match = re.fullmatch( r"([a-z ]+) bags contain ((?:\d+ [a-z ]+ bags?(?:, )?)+)\.", spec_string) if content_match is None: return bag, contents = content_match.groups() contents = contents.strip().split(", ") contents = [ re.fullmatch(r"(\d+) ([a-z ]+) bags?,?", content).groups() for content in contents ] contents = [(int(content[0]), content[1]) for content in contents] for content in contents: relationship_map[bag]["contains"].append(content) relationship_map[content[1]]["contained by"].append((content[0], bag)) if __name__ == "__main__": spec = utils.parse_file_lines("day7_input.txt", str) input_map = parse_all_lines(spec) gold_parents = set() find_parents(input_map, "shiny gold", gold_parents) print("Part 1: {}".format(len(gold_parents))) print("Part 2: {}".format(count_bags(input_map, "shiny gold")))
def test_first(self): nums = utils.parse_file_lines("day9_test_input1.txt", int) self.assertEqual(day9.find_invalid_number(nums, 5), 127)
def test_second(self): nums = utils.parse_file_lines("day1_test_input1.txt", int) self.assertEqual(day1.find_sum_3(nums, 2020), 241861950)
import utils def find_sum_2(nums, expected_sum): for i, num1 in enumerate(nums): for num2 in nums[i + 1:]: if num1 + num2 == expected_sum: return num1 * num2 raise Exception("No pair summed to {}".format(expected_sum)) def find_sum_3(nums, expected_sum): for i, num1 in enumerate(nums): for num2 in nums[i + 1:]: for num3 in nums[i + 2:]: if num1 + num2 + num3 == expected_sum: return num1 * num2 * num3 raise Exception("No triplet summed to {}".format(expected_sum)) if __name__ == "__main__": input_nums = utils.parse_file_lines("day1_input.txt", int) print("Part 1: {}".format(find_sum_2(input_nums, 2020))) print("Part 2: {}".format(find_sum_3(input_nums, 2020)))
def test_second(self): spec = utils.parse_file_lines("day7_test_input1.txt", str) relationship_map = day7.parse_all_lines(spec) self.assertEqual(day7.count_bags(relationship_map, "shiny gold"), 32)
def test_first(self): program = utils.parse_file_lines("day8_test_input1.txt", str) program = [line.strip() for line in program] self.assertEqual(day8.execute_code(program)[0], 5)
def test_first(self): passwords = utils.parse_file_lines("day2_test_input1.txt", str) self.assertEqual(day2.find_valid_passwords(passwords), 2)
def test_first(self): batch = "".join(utils.parse_file_lines("day4_test_input1.txt", str)) + "\n" self.assertEqual(day4.find_valid_passports(batch), 2)
prev_state = seating.state_map.copy() while True: seating.update_state_1() new_state = seating.state_map if prev_state == new_state: break prev_state = new_state.copy() return sum([seating.state_map.get((x, y), ".") == "#" for x, y in product(range(seating.width), range(seating.height))]) def stabilize_seating_2(pattern): seating = Seating(pattern) prev_state = seating.state_map.copy() while True: seating.update_state_2() new_state = seating.state_map if prev_state == new_state: break prev_state = new_state.copy() return sum([seating.state_map.get((x, y), ".") == "#" for x, y in product(range(seating.width), range(seating.height))]) if __name__ == "__main__": parsed_strings = utils.parse_file_lines("day11_input.txt", str) print("Part 1: {}".format(stabilize_seating_1(parsed_strings))) print("Part 2: {}".format(stabilize_seating_2(parsed_strings)))
def test_second(self): program = utils.parse_file_lines("day14_test_input2.txt", str) self.assertEqual(day14.initialize_2(program), 208)
def test_first(self): program = utils.parse_file_lines("day14_test_input1.txt", str) self.assertEqual(day14.initialize(program), 165)
def test_first(self): input_spec = "".join( utils.parse_file_lines("day16_test_input1.txt", str)) self.assertEqual(day16.find_error_rate(input_spec), 71)
update_mask, int_1, int_2 = parse_line(line.strip()) if update_mask: mask_or = int_1 mask_and = int_2 else: addr = int_1 val = int_2 memory[addr] = (val | mask_or) & mask_and return sum(memory.values()) def initialize_2(program): mask = format(0, "036b") memory = {} for line in program: update_mask, val_1, int_2 = parse_line_2(line.strip()) if update_mask: mask = val_1 else: addr_spec = apply_bitmask(mask, val_1) addrs = enumerate_addrs(addr_spec, []) for addr in addrs: memory[addr] = int_2 return sum(memory.values()) if __name__ == "__main__": input_program = utils.parse_file_lines("day14_input.txt", str) print("Part 1: {}".format(initialize(input_program))) print("Part 2: {}".format(initialize_2(input_program)))
def test_first(self): input_pattern = utils.parse_file_lines("day3_test_input1.txt", str) hill = day3.Hill(input_pattern) self.assertEqual(hill.check_angle(3, 1), 7)