import logging from sys import stdout # The first section specifies the page ordering rules, one per line. # The first rule, 47|53, means that if an update includes both # page number 47 and page number 53, then page number 47 must be # printed at some point before page number 53. (47 doesn't necessarily # need to be immediately before 53; other pages are allowed to be # between them.) # The second section specifies the page numbers of each update. # Because most safety manuals are different, the pages needed in the # updates are different too. The first update, 75,47,61,53,29, means # that the update consists of page numbers 75, 47, 61, 53, and 29. # For each of the incorrectly-ordered updates, use the page ordering # rules to put the page numbers in the right order. # Find the updates which are not in the correct order. What do you get # if you add up the middle page numbers after correctly ordering # just those updates? LOG_FILENAME = "./day04-1.log" INPUT_FILENAME = "./input04.txt" logger = logging.Logger(__name__) formatter = logging.Formatter('[%(asctime)s][%(levelname)s] %(message)s') sh = logging.StreamHandler(stdout) sh.setLevel(logging.INFO) sh.setFormatter(formatter) fh = logging.FileHandler(LOG_FILENAME, mode="w", encoding="utf-8") fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) logger.addHandler(sh) logger.addHandler(fh) def main052(): with open("./input05.txt", "r", encoding="utf-8") as f: lines = [l.strip() for l in f.readlines()] rules = [] updates = [] for i, line in enumerate(lines): if "|" not in line: first_update = i + 1 break rules.append([int(x) for x in line.split("|")]) for i, line in enumerate(lines[first_update:]): updates.append([int(x) for x in line.split(",")]) valid_updates = [] invalid_updates = [] new_invalid_updates = [] total_vu = 0 total_iu = 0 for u in updates: relevant_rules = [r for r in rules if all([x in u for x in r])] all_valid = all([u.index(rule[0]) < u.index(rule[1]) for rule in relevant_rules]) if all_valid: valid_updates.append(u) total_vu += u[(len(u)-1)//2] else: invalid_updates.append(u) logger.info(f"Applying rules to {u}...") while not all_valid: logger.info(f"{u} still doesn't meet all the rules.") for rule in relevant_rules: i1 = u.index(rule[0]) i2 = u.index(rule[1]) if i1 > i2: u[i1] = rule[1] u[i2] = rule[0] logger.info(f"Swapping {rule[0]} and {rule[1]}, u is now {u}.") all_valid = all([u.index(rule[0]) < u.index(rule[1]) for rule in relevant_rules]) new_invalid_updates.append(u) middle_val = u[(len(u)-1)//2] logger.info(f"Adding {middle_val} to {total_iu} to get {total_iu + middle_val}.") total_iu += middle_val print(total_vu) logger.info(f"Total of invalid update centers is {total_iu}.") if __name__ == "__main__": main052()