Files
adventofcode/2024/05/puzzle1.py

70 lines
1.7 KiB
Python

verbose = False
def indices(lst, element):
"""
See <https://stackoverflow.com/questions/6294179/how-to-find-all-occurrences-of-an-element-in-a-list>.
"""
result = []
offset = -1
while True:
try:
offset = lst.index(element, offset+1)
except ValueError:
return result
result.append(offset)
def load_input(filename="input"):
with open(filename, "r") as fp:
lines = fp.read().splitlines()
# Find the empty line/separator.
sep = lines.index("")
# Handle rules
rule_lines = lines[:sep]
rules = [tuple(map(int, l.split("|"))) for l in rule_lines]
# Handle lines
update_lines = lines[sep + 1:]
updates = [list(map(int, l.split(","))) for l in update_lines]
return rules, updates
def is_update_legal(update, rules, print_offence=False) -> bool:
for rule in rules:
# Find indices of left hand side and right hand side
lhs, rhs = rule
if not lhs in update or not rhs in update:
continue
# This reminds me of limes inferior and limes superior.
# Thanks, Mueger.
if max(indices(update, lhs)) > min(indices(update, rhs)):
if print_offence:
print(f"Rule", rule, "offended by update", update)
return False
return True
def middle_page_num(update) -> int:
return update[len(update) // 2]
if __name__ == "__main__":
rules, updates = load_input()
indices_legal = []
middle_sum = 0
for idx, update in enumerate(updates):
if is_update_legal(update, rules):
if verbose:
print(update, " is legal")
indices_legal.append(idx)
middle_sum += middle_page_num(update)
else:
if verbose:
print(update, " is illegal")
if verbose:
print(indices_legal)
print(f"The sum of middle page numbers of legal updates is {middle_sum}.")