def part_2(): instructions = get_strings_by_lines('8.txt') for idx in range(len(instructions)): # Copy the instructions copy = [] + instructions log(f'trying flipping instruction {idx}') if instructions[idx][:3] == 'jmp': copy[idx] = 'nop' + instructions[idx][3:] elif instructions[idx][:3] == 'nop': copy[idx] = 'jmp' + instructions[idx][3:] else: log('skipping instr: ' + instructions[idx]) acc, pointer = 0, 0 already_run = set() while pointer not in already_run: instr = copy[pointer] already_run.add(pointer) acc, pointer = run_instr(instr, acc, pointer) if pointer == len(instructions): log(f'found it flipping idx {idx}') return acc log('Failed idx {idx}') return None
def parse_tree(): rules = get_strings_by_lines('7.txt') for rule in rules: specifier, contain_string = rule.split(' bags contain ') # Add this object to the tree if we don't know anything about it if specifier not in tree: curr_bag = Bag(specifier) tree[specifier] = curr_bag else: curr_bag = tree[specifier] for spec in contain_string.strip('.').split(', '): spec = spec.strip('s') if spec == 'no other bag': continue else: number, bag = parse('{:d} {} bag', spec) if bag in tree: target_bag = tree[bag] else: target_bag = Bag(bag) tree[bag] = target_bag curr_bag.children[bag] = number curr_bag.contains.add(bag) target_bag.parents.add(curr_bag.name)
def part_2(): earliest, bus_list = get_strings_by_lines('13.txt') busses = [ bus for bus in bus_list.split(',') if bus ] # Fulfill the constraints one at a time - Once you find a number satisfying # Two divisors, future values must be a multiple of that value. # AKA for divisors w,x,y,z the minimum value satisfying y must be # <the minimum value satisfying w,x> + (w * x) # And then the minimum value satisfying z must be # <the minimum value satisfying w,x,y> + (w * x * y) # ETC. current_time = 0 inc = 1 for idx in range(len(busses)): if busses[idx] == 'x': log(f'Skipping idx {idx}') continue curr_bus = int(busses[idx]) while (current_time + idx) % curr_bus != 0: current_time += inc log(f'constraint fulfilled! {curr_bus}') inc *= curr_bus log(f'New Inc: {inc}') return current_time
def part_1(): x, y, dir = 0, 0, 'E' log(f"({x}, {y}, {dir})") for instr_str in get_strings_by_lines('12.txt'): x, y, dir = handle_instruction(x, y, dir, instr_str) log(f"({x}, {y}, {dir})") return abs(x) + abs(y)
def part_2(): x, y, wx, wy = 0, 0, 10, 1 log(f"({x}, {y}), ({wx}, {wy})") for instr_str in get_strings_by_lines('12.txt'): x, y, wx, wy = handle_instruction_with_waypoint( x, y, wx, wy, instr_str) log(f"({x}, {y}), ({wx}, {wy})") return abs(x) + abs(y)
def part_1(): instructions = get_strings_by_lines('8.txt') acc, pointer = 0, 0 already_run = set() while pointer not in already_run: instr = instructions[pointer] already_run.add(pointer) acc, pointer = run_instr(instr, acc, pointer) return acc
def part_1(): earliest, bus_list = get_strings_by_lines('13.txt') current_time = int(earliest) busses = [ int(bus) for bus in bus_list.split(',') if bus and bus != 'x'] while True: log(f'Testing: {current_time}') for bus in busses: if current_time % bus == 0: log('FOUND IT') return (current_time - int(earliest)) * bus current_time += 1
def part_1(): boarding_passes = get_strings_by_lines('5.txt') max = 0 for bp in boarding_passes: row = bin_search(127, bp[:7]) col = bin_search(8, bp[7:]) id = (row * 8) + col if id > max: max = id return max
def part_2(): grid = [[char for char in line] for line in get_strings_by_lines('11.txt')] changed = True iterations = 0 print_grid(grid) while changed: grid, changed = iterate(grid, False) iterations += 1 log(f"iterated {iterations} times") print_grid(grid) return count_grid(grid)
def part_2(): instructions = get_strings_by_lines('14.txt') memory = {} mask = '' for inst in instructions: if inst[:4] == 'mask': (mask, ) = parse('mask = {}', inst) log(f"set mask to {mask}") else: address, value = parse('mem[{:d}] = {:d}', inst) memory = write_value_to_decoded_registers(memory, address, mask, value) log(memory) return sum(memory.values())
def part_1(): instructions = get_strings_by_lines('14.txt') memory = {} and_mask, or_mask = 0, 0 for inst in instructions: if inst[:4] == 'mask': (new_mask, ) = parse('mask = {}', inst) and_mask, or_mask = set_bitmask(new_mask) else: address, value = parse('mem[{:d}] = {:d}', inst) memory = set_register(memory, address, value, and_mask, or_mask) log(memory) return sum(memory.values())
def part_2(): rows = get_strings_by_lines('3.txt') x = 0 tree_counts = [ count_trees(rows, slope) for slope in [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)] ] log(tree_counts) # return functools.reduce(lambda x, y: x*y, tree_counts) # Yeah, Robin, I know how to reduce stuff too product = 1 for count in tree_counts: product *= count return product
def part_1(): input_arr = get_strings_by_lines('2.txt') valid_count = 0 # Loop through every pair in the array for input in input_arr: min, max, char, password = parse('{:d}-{:d} {:l}: {:w}', input) count = password.count(char) log(f"Testing {password} for {min} to {max} {char}'s") if min <= count <= max: log(f"\tYES") valid_count += 1 else: log(f"\tNO") return valid_count
def part_2(): boarding_passes = get_strings_by_lines('5.txt') ids = [] for bp in boarding_passes: row = bin_search(127, bp[:7]) col = bin_search(8, bp[7:]) ids += [(row * 8) + col] ids.sort() log(ids) for idx in range(1, len(ids)): # Did we skip a number? if ids[idx] - ids[idx - 1] != 1: return ids[idx] - 1 # Return the skipped number return None
def part_2(): input_arr = get_strings_by_lines('2.txt') valid_count = 0 # Loop through every pair in the array for input in input_arr: idx_a, idx_b, char, password = parse('{:d}-{:d} {:l}: {:w}', input) count = password.count(char) log(f"Testing {password} for {char} at indexes {idx_a} and {idx_b}") # convert from indexing at 0 to indexing at 1 # And cast to bools to use the exclusive or operator if bool(password[idx_a - 1] == char) ^ bool(password[idx_b - 1] == char): log(f"\tYES") valid_count += 1 else: log(f"\tNO") return valid_count
def part_1(): rows = get_strings_by_lines('3.txt') x = 0 tree_count = 0 return count_trees(rows, (3, 1))
lib.config.DAY_NUMBER = args.day # Import helper functions from lib.helpers import log, get_strings_by_lines if __name__ == "__main__": # import the library dynamically lib_name = f"problems.day_{args.day}" solver = importlib.import_module(lib_name) # Choose day 1 or day 2 if args.test: if args.part != 2: log('\nTesting part 1...') computed = solver.part_1() all_answers = get_strings_by_lines('answers-part-1.txt') answer = all_answers[args.day - 1] if str(computed) == answer: print(f"Part 1: PASSED ({computed})") else: print(f"Part 1: FAILED") print(f"\tcomputed: {computed}") print(f"\tintended: {answer}") if args.part != 1: log('\nTesting part 2...') computed = solver.part_2() all_answers = get_strings_by_lines('answers-part-2.txt') answer = all_answers[args.day - 1] if str(computed) == answer: print(f"Part 2: PASSED ({computed})") else: