import sys import os sys.path.insert(1, os.path.abspath('../../')) from python_tools.aoc_utils import * import collections as C rules = [] updates = [] def get_middle(u): assert(len(u) % 2 == 1) return u[int((len(u)-1)/2)] def check_rule_break(r, visited): for i in visited: if i in r: return True return False def part_one(rules, updates): pt_1 = 0 G = C.defaultdict(list) for r in rules: G[r[0]].append(r[1]) count = 0 for u in updates: update_valid = True visited = [] for i in u: if check_rule_break(G[i], visited): update_valid = False break else: visited.append(i) if update_valid: # print(f"{count} valid {get_middle(u)}, {u}") pt_1 += get_middle(u) count += 1 print("Part One: ", pt_1) def swap_order(u, G): for count, i in enumerate(u): for c in range(count): if i in G[u[c]]: u.insert(c, u.pop(count)) break def part_two(input): pt_2 = 0 G = C.defaultdict(list) for r in rules: G[r[0]].append(r[1]) count = 0 for u in updates: order_needs_to_be_swapped = False visited = [] for i in u: if check_rule_break(G[i], visited): order_needs_to_be_swapped = True break else: visited.append(i) if order_needs_to_be_swapped: swap_order(u, G) pt_2 += get_middle(u) count += 1 print("Part One: ", pt_2) def main(): f = open("input.txt") contents = f.read().split() for c in contents: if "|" in c: rules.append(list(map(int, (c.split("|"))))) elif "," in c: updates.append(list(map(int,c.split(",")))) part_one(rules, updates) part_two(contents) if __name__ == "__main__": main()