53 lines
1.4 KiB
Python
53 lines
1.4 KiB
Python
from common import *
|
|
from pprint import pprint
|
|
|
|
|
|
def partTwo(instr: str) -> int:
|
|
rules, my_ticket, tickets = parse(instr)
|
|
|
|
# purge bad indexes
|
|
_, invalid_indexes = find_invalid(rules, tickets)
|
|
invalid_indexes = list(reversed(sorted(invalid_indexes)))
|
|
|
|
for idx in invalid_indexes:
|
|
tickets.pop(idx)
|
|
|
|
ticket_length = len(tickets[0].fields)
|
|
num_tickets = len(tickets)
|
|
num_rules = len(rules)
|
|
|
|
candidates = {rule.name: set() for rule in rules}
|
|
|
|
for col in range(ticket_length):
|
|
values = [ticket.fields[col] for ticket in tickets]
|
|
|
|
for rule_idx, rule in enumerate(rules):
|
|
complete_match = True
|
|
for v in values:
|
|
if not test_value(v, rule.ranges):
|
|
complete_match = False
|
|
break
|
|
|
|
if complete_match:
|
|
candidates[rule.name].add(col)
|
|
|
|
parameter_indexes = {}
|
|
removed = set()
|
|
|
|
product = 1
|
|
|
|
for col in range(ticket_length):
|
|
for name in candidates:
|
|
candidates_set = candidates[name] - removed
|
|
|
|
if len(candidates_set) == 1:
|
|
idx = candidates_set.pop()
|
|
parameter_indexes[name] = idx
|
|
removed.add(idx)
|
|
|
|
product = 1
|
|
for param in parameter_indexes:
|
|
if "departure" in param:
|
|
product *= my_ticket.fields[parameter_indexes[param]]
|
|
|
|
return product
|