|
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- 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()
|