From 9edd5cd47fcdae8bc54dae6b253e4966d6284878 Mon Sep 17 00:00:00 2001 From: Drew Winstel Date: Wed, 16 Dec 2020 09:05:52 -0600 Subject: [PATCH 1/3] Switch to a two-pass system so it works in the general case --- Drew/drew_day16.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Drew/drew_day16.py b/Drew/drew_day16.py index 7bf306e..0deef0b 100644 --- a/Drew/drew_day16.py +++ b/Drew/drew_day16.py @@ -94,9 +94,10 @@ def part_two(puzzle_input: str) -> int: if all(number_in_ranges(value, field_rules) for value in field_values): field_map[field_name].append(field_index) definite_fields = {} - for field_name, field_index_candidates in field_map.items(): + for field_name, field_index_candidates in list(field_map.items()): if len(field_index_candidates) == 1: definite_fields[field_name] = field_index_candidates[0] + del field_map[field_name] result = 1 while field_map: # NOTE this runs indefinitely on mine. Let's just keep going until we get our 6 @@ -104,6 +105,15 @@ def part_two(puzzle_input: str) -> int: # what we're doing is looping through each field to see if we have isolated the candidate # field indexes down to one value + + # first, process singletons + for field_name, field_index_candidates in list(field_map.items()): + if len(field_index_candidates) == 1: + if len(field_index_candidates) == 1: + # yay we've isolated one candidate + definite_fields[field_name] = field_index_candidates[0] + del field_map[field_name] + # then do the rest for field_name, field_index_candidates in list(field_map.items()): if field_name in definite_fields: # we've already matched it. Kill it. @@ -115,9 +125,9 @@ def part_two(puzzle_input: str) -> int: field_index_candidates.remove(value) except ValueError: pass - if len(field_index_candidates) == 1: - # yay we've isolated one candidate - definite_fields[field_name] = field_index_candidates[0] + if not field_index_candidates: + raise ValueError(f"No viable candidates for {field_name}") + # by some miracle, have we gotten our 6? departure_values = list( val for key, val in definite_fields.items() if key.startswith("departure") From 5d26446142097bca6265efbb132d128f91e87ed1 Mon Sep 17 00:00:00 2001 From: Drew Winstel Date: Wed, 16 Dec 2020 10:59:58 -0600 Subject: [PATCH 2/3] Exclude tickets with a zero value from the part two candidates This was causing an incorrect solution on someone else's input --- Drew/drew_day16.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Drew/drew_day16.py b/Drew/drew_day16.py index 0deef0b..70e3ef2 100644 --- a/Drew/drew_day16.py +++ b/Drew/drew_day16.py @@ -82,7 +82,9 @@ def part_two(puzzle_input: str) -> int: rules = puzzle["rules"] other_tickets = puzzle["nearby tickets"] valid_tickets = [ - ticket for ticket in other_tickets if not get_invalid_value(ticket, rules) + ticket + for ticket in other_tickets + if 0 not in ticket and not get_invalid_value(ticket, rules) ] values_by_field = [] # think of this as a very ugly means of transposing a table From bc77e989f6d7e467901f470e0177c295f823c6c1 Mon Sep 17 00:00:00 2001 From: Drew Winstel Date: Wed, 16 Dec 2020 11:02:51 -0600 Subject: [PATCH 3/3] Add clarifying comment --- Drew/drew_day16.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Drew/drew_day16.py b/Drew/drew_day16.py index 70e3ef2..0d508c4 100644 --- a/Drew/drew_day16.py +++ b/Drew/drew_day16.py @@ -102,9 +102,6 @@ def part_two(puzzle_input: str) -> int: del field_map[field_name] result = 1 while field_map: - # NOTE this runs indefinitely on mine. Let's just keep going until we get our 6 - # departure fields isolated - # what we're doing is looping through each field to see if we have isolated the candidate # field indexes down to one value @@ -140,6 +137,7 @@ def part_two(puzzle_input: str) -> int: result *= puzzle["your ticket"][i] return result + # we only get here with the test input return result