forked from thib8956/advent-of-code-2k20
wip
This commit is contained in:
parent
5d8d3ff7dc
commit
930119ce7e
@ -8,11 +8,12 @@ identify invalid nearby tickets by considering only whether tickets contain valu
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
rules, my_ticket, tickets = open("input.txt").read().split("\n\n")
|
rules, my_ticket, other_tickets = open("input.txt").read().split("\n\n")
|
||||||
rules = parse_fields(rules)
|
rules = parse_fields(rules)
|
||||||
tickets = tickets.splitlines()[1:]
|
my_ticket = my_ticket.splitlines()[1]
|
||||||
print("Ticket scanning error rate ", part1(tickets, rules))
|
other_tickets = other_tickets.splitlines()[1:]
|
||||||
part2(tickets, rules)
|
print("Ticket scanning error rate ", part1(other_tickets, rules))
|
||||||
|
part2(my_ticket, other_tickets, rules)
|
||||||
|
|
||||||
|
|
||||||
def parse_fields(fields):
|
def parse_fields(fields):
|
||||||
@ -35,31 +36,68 @@ def validate_ticket(ticket, rules):
|
|||||||
invalid_fields = []
|
invalid_fields = []
|
||||||
for value in ticket.split(","):
|
for value in ticket.split(","):
|
||||||
value = int(value)
|
value = int(value)
|
||||||
validations = (any(value in r for r in rule) for rule in rules.values())
|
if not validate_field(value, *rules.values()):
|
||||||
if not any(validations):
|
|
||||||
invalid_fields.append(value)
|
invalid_fields.append(value)
|
||||||
return invalid_fields
|
return invalid_fields
|
||||||
|
|
||||||
|
|
||||||
def part2(tickets, rules):
|
def validate_field(field, *rules):
|
||||||
# filter only valid tickets
|
validations = (any(field in r for r in rule) for rule in rules)
|
||||||
valid_tickets = [ticket for ticket in tickets if validate_ticket(ticket, rules) == []]
|
return any(validations)
|
||||||
|
|
||||||
# field => [matching_rules]
|
|
||||||
# eliminate field with only one matching rule
|
def part2(my_ticket, other_tickets, rules):
|
||||||
all_matching_rules = {}
|
# filter only valid tickets
|
||||||
for ticket in valid_tickets:
|
valid_tickets = [ticket for ticket in other_tickets if validate_ticket(ticket, rules) == []]
|
||||||
possible_matching_rules = defaultdict(set)
|
valid_tickets.append(my_ticket) # my ticket is valid
|
||||||
for field_index, field_value in enumerate(ticket.split(",")):
|
|
||||||
field_value = int(field_value)
|
# possible field for each index of a ticket
|
||||||
for name, rule in rules.items():
|
candidates = defaultdict(set)
|
||||||
match = {r: field_value in r for r in rule}
|
for index in range(len(rules)):
|
||||||
if any(match.values()):
|
def inner():
|
||||||
possible_matching_rules[name].add(field_index)
|
for rule_name, constraints in rules.items():
|
||||||
all_matching_rules[ticket]= possible_matching_rules
|
for ticket in valid_tickets:
|
||||||
|
field_value = int(ticket.split(",")[index])
|
||||||
|
if not validate_field(field_value, constraints):
|
||||||
|
return
|
||||||
|
candidates[index].add(rule_name)
|
||||||
|
inner()
|
||||||
|
|
||||||
|
sorted_candidates = sort_candidates(candidates)
|
||||||
|
|
||||||
|
fields_indexes = {}
|
||||||
|
try:
|
||||||
|
while len(fields_indexes) != len(rules):
|
||||||
|
index, found = sorted_candidates.popitem()
|
||||||
|
found = next(iter(found))
|
||||||
|
fields_indexes[index] = found
|
||||||
|
sorted_candidates = remove_item(sorted_candidates, found)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
fields_indexes = {k: v for k,v in fields_indexes.items() if v.startswith('departure')}
|
||||||
|
|
||||||
|
total = 1
|
||||||
|
my_ticket = my_ticket.split(',')
|
||||||
|
for index in fields_indexes:
|
||||||
|
total *= int(my_ticket[index])
|
||||||
a = 1
|
a = 1
|
||||||
|
|
||||||
# repeat
|
|
||||||
|
def sort_candidates(c):
|
||||||
|
return {x: c[x] for x in sorted(c, key=lambda k: len(c[k]), reverse=True)}
|
||||||
|
|
||||||
|
def remove_item(candidates, item):
|
||||||
|
ret = {}
|
||||||
|
for key, value in candidates.items():
|
||||||
|
try:
|
||||||
|
value.remove(item)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
ret[key] = value
|
||||||
|
|
||||||
|
#candidates = {k: set(v - item) for k,v in candidates.items()}
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user