[Advent of Code 2024](https://adventofcode.com/2024)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

day05-2.py 3.1KB

2 weeks ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import logging
  2. from sys import stdout
  3. # The first section specifies the page ordering rules, one per line.
  4. # The first rule, 47|53, means that if an update includes both
  5. # page number 47 and page number 53, then page number 47 must be
  6. # printed at some point before page number 53. (47 doesn't necessarily
  7. # need to be immediately before 53; other pages are allowed to be
  8. # between them.)
  9. # The second section specifies the page numbers of each update.
  10. # Because most safety manuals are different, the pages needed in the
  11. # updates are different too. The first update, 75,47,61,53,29, means
  12. # that the update consists of page numbers 75, 47, 61, 53, and 29.
  13. # For each of the incorrectly-ordered updates, use the page ordering
  14. # rules to put the page numbers in the right order.
  15. # Find the updates which are not in the correct order. What do you get
  16. # if you add up the middle page numbers after correctly ordering
  17. # just those updates?
  18. LOG_FILENAME = "./day04-1.log"
  19. INPUT_FILENAME = "./input04.txt"
  20. logger = logging.Logger(__name__)
  21. formatter = logging.Formatter('[%(asctime)s][%(levelname)s] %(message)s')
  22. sh = logging.StreamHandler(stdout)
  23. sh.setLevel(logging.INFO)
  24. sh.setFormatter(formatter)
  25. fh = logging.FileHandler(LOG_FILENAME, mode="w", encoding="utf-8")
  26. fh.setLevel(logging.DEBUG)
  27. fh.setFormatter(formatter)
  28. logger.addHandler(sh)
  29. logger.addHandler(fh)
  30. def main052():
  31. with open("./input05.txt", "r", encoding="utf-8") as f:
  32. lines = [l.strip() for l in f.readlines()]
  33. rules = []
  34. updates = []
  35. for i, line in enumerate(lines):
  36. if "|" not in line:
  37. first_update = i + 1
  38. break
  39. rules.append([int(x) for x in line.split("|")])
  40. for i, line in enumerate(lines[first_update:]):
  41. updates.append([int(x) for x in line.split(",")])
  42. valid_updates = []
  43. invalid_updates = []
  44. new_invalid_updates = []
  45. total_vu = 0
  46. total_iu = 0
  47. for u in updates:
  48. relevant_rules = [r for r in rules if all([x in u for x in r])]
  49. all_valid = all([u.index(rule[0]) < u.index(rule[1]) for rule in relevant_rules])
  50. if all_valid:
  51. valid_updates.append(u)
  52. total_vu += u[(len(u)-1)//2]
  53. else:
  54. invalid_updates.append(u)
  55. logger.info(f"Applying rules to {u}...")
  56. while not all_valid:
  57. logger.info(f"{u} still doesn't meet all the rules.")
  58. for rule in relevant_rules:
  59. i1 = u.index(rule[0])
  60. i2 = u.index(rule[1])
  61. if i1 > i2:
  62. u[i1] = rule[1]
  63. u[i2] = rule[0]
  64. logger.info(f"Swapping {rule[0]} and {rule[1]}, u is now {u}.")
  65. all_valid = all([u.index(rule[0]) < u.index(rule[1]) for rule in relevant_rules])
  66. new_invalid_updates.append(u)
  67. middle_val = u[(len(u)-1)//2]
  68. logger.info(f"Adding {middle_val} to {total_iu} to get {total_iu + middle_val}.")
  69. total_iu += middle_val
  70. print(total_vu)
  71. logger.info(f"Total of invalid update centers is {total_iu}.")
  72. if __name__ == "__main__":
  73. main052()