79 lines
2.0 KiB
Python
79 lines
2.0 KiB
Python
import matrix
|
|
import shared
|
|
|
|
def read(rows):
|
|
second = False
|
|
rules = []
|
|
updates = []
|
|
for row in rows:
|
|
if second:
|
|
updates.append(list(map(int, row.split(","))))
|
|
elif row == "":
|
|
second = True
|
|
else:
|
|
rules.append(list(map(int, row.split("|"))))
|
|
return rules, updates
|
|
|
|
def get_bads(rules, updates):
|
|
bads = []
|
|
for idx, update in enumerate(updates):
|
|
for first, second in rules:
|
|
if first in update and second in update:
|
|
first_idx = update.index(first)
|
|
second_idx = update.index(second)
|
|
if first_idx > second_idx:
|
|
bads.append(idx)
|
|
break
|
|
return bads
|
|
|
|
# @shared.profile
|
|
def part1(rows):
|
|
rules, updates = read(rows)
|
|
bads = get_bads(rules, updates)
|
|
total = 0
|
|
for idx, update in enumerate(updates):
|
|
if idx in bads:
|
|
continue
|
|
total += update[len(update) // 2]
|
|
print(total)
|
|
|
|
def fix_bad(rules, bad):
|
|
for first, second in rules:
|
|
if first in bad and second in bad:
|
|
first_idx = bad.index(first)
|
|
second_idx = bad.index(second)
|
|
if first_idx > second_idx:
|
|
bad[first_idx], bad[second_idx] = bad[second_idx], bad[first_idx]
|
|
return bad
|
|
|
|
# @shared.profile
|
|
def part2(rows):
|
|
rules, updates = read(rows)
|
|
bads = get_bads(rules, updates)
|
|
total = 0
|
|
for idx in bads:
|
|
bad = updates[idx]
|
|
while True:
|
|
after = fix_bad(rules, bad[:])
|
|
if bad == after:
|
|
break
|
|
bad = after
|
|
total += bad[len(bad) // 2]
|
|
print(total)
|
|
|
|
|
|
def main():
|
|
rows = [row for row in shared.load_rows(5)]
|
|
with shared.elapsed_timer() as elapsed:
|
|
part1(rows)
|
|
print("🕒", elapsed())
|
|
|
|
rows = [row for row in shared.load_rows(5, True)]
|
|
with shared.elapsed_timer() as elapsed:
|
|
part2(rows)
|
|
print("🕒", elapsed())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|