day16: cleaner code
This commit is contained in:
parent
07d49a707b
commit
2d6dd0e074
120
day16.py
120
day16.py
@ -5,15 +5,15 @@ TEST_SOLUTION_PART1 = 71
|
|||||||
TEST_SOLUTION_PART2 = 7
|
TEST_SOLUTION_PART2 = 7
|
||||||
|
|
||||||
|
|
||||||
def part1(test_mode=False):
|
def parse_input(to_parse):
|
||||||
my_input = aoclib.getInputAsArray(day=DAY, test=test_mode)
|
|
||||||
|
|
||||||
restraints = {}
|
restraints = {}
|
||||||
|
my_ticket = []
|
||||||
other_tickets = []
|
other_tickets = []
|
||||||
|
|
||||||
for i, line in enumerate(my_input):
|
for i, line in enumerate(to_parse):
|
||||||
if not line:
|
if not line:
|
||||||
other_tickets = my_input[i+5:]
|
my_ticket = list(map(int, to_parse[i+2].split(",")))
|
||||||
|
other_tickets = [list(map(int, ticket.split(","))) for ticket in to_parse[i+5:]]
|
||||||
break
|
break
|
||||||
|
|
||||||
field, limits = line.split(": ")
|
field, limits = line.split(": ")
|
||||||
@ -22,94 +22,76 @@ def part1(test_mode=False):
|
|||||||
min_hi, max_hi = limit_hi.split("-")
|
min_hi, max_hi = limit_hi.split("-")
|
||||||
restraints[field] = [(int(min_low), int(max_low)), (int(min_hi), int(max_hi))]
|
restraints[field] = [(int(min_low), int(max_low)), (int(min_hi), int(max_hi))]
|
||||||
|
|
||||||
|
return restraints, my_ticket, other_tickets
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_number(number, restraints):
|
||||||
|
for restraint in restraints.values():
|
||||||
|
if restraint[0][0] <= number <= restraint[0][1] or restraint[1][0] <= number <= restraint[1][1]:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def part1(test_mode=False):
|
||||||
|
my_input = aoclib.getInputAsArray(day=DAY, test=test_mode)
|
||||||
|
restraints, _, other_tickets = parse_input(my_input)
|
||||||
|
|
||||||
invalid_numbers = []
|
invalid_numbers = []
|
||||||
for ticket in other_tickets:
|
for ticket in other_tickets:
|
||||||
for number in ticket.split(","):
|
for number in ticket:
|
||||||
valid = False
|
if not is_valid_number(number, restraints):
|
||||||
number = int(number)
|
|
||||||
for field in restraints:
|
|
||||||
if restraints[field][0][0] <= number <= restraints[field][0][1] or \
|
|
||||||
restraints[field][1][0] <= number <= restraints[field][1][1]:
|
|
||||||
valid = True
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
if not valid:
|
|
||||||
invalid_numbers.append(number)
|
invalid_numbers.append(number)
|
||||||
|
|
||||||
return sum(invalid_numbers)
|
return sum(invalid_numbers)
|
||||||
|
|
||||||
|
|
||||||
def part2(test_mode=False):
|
def get_single_possible_positions(possible_positions):
|
||||||
my_input = aoclib.getInputAsArray(day=DAY, test=test_mode)
|
single_possibilities = []
|
||||||
|
while 1:
|
||||||
|
all_done = True
|
||||||
|
for field, possibilities in possible_positions.items():
|
||||||
|
if len(possibilities) == 1:
|
||||||
|
possible_position = possibilities[0]
|
||||||
|
if possible_position not in single_possibilities:
|
||||||
|
all_done = False
|
||||||
|
single_possibilities.append(possible_position)
|
||||||
|
for check_field, check_positions in possible_positions.items():
|
||||||
|
if possible_position in check_positions and len(check_positions) > 1:
|
||||||
|
possible_positions[check_field].remove(possible_position)
|
||||||
|
|
||||||
restraints = {}
|
if all_done:
|
||||||
possible_positions = {}
|
|
||||||
my_ticket = ''
|
|
||||||
other_tickets = []
|
|
||||||
|
|
||||||
for i, line in enumerate(my_input):
|
|
||||||
if not line:
|
|
||||||
my_ticket = my_input[i+2]
|
|
||||||
other_tickets = my_input[i+5:]
|
|
||||||
break
|
break
|
||||||
|
|
||||||
field, limits = line.split(": ")
|
return possible_positions
|
||||||
limit_low, limit_hi = limits.split(" or ")
|
|
||||||
min_low, max_low = limit_low.split("-")
|
|
||||||
min_hi, max_hi = limit_hi.split("-")
|
def part2(test_mode=False):
|
||||||
restraints[field] = [(int(min_low), int(max_low)), (int(min_hi), int(max_hi))]
|
my_input = aoclib.getInputAsArray(day=DAY, test=test_mode)
|
||||||
|
restraints, my_ticket, other_tickets = parse_input(my_input)
|
||||||
|
possible_positions = {}
|
||||||
|
num_fields = len(my_ticket)
|
||||||
|
|
||||||
num_fields = len(my_ticket.split(','))
|
|
||||||
for field in restraints:
|
for field in restraints:
|
||||||
possible_positions[field] = [x for x in range(num_fields)]
|
possible_positions[field] = list(range(num_fields))
|
||||||
|
|
||||||
for ticket in other_tickets:
|
for ticket in other_tickets:
|
||||||
invalid = False
|
invalid = False
|
||||||
for position, number in enumerate(ticket.split(",")):
|
for number in ticket:
|
||||||
valid = False
|
if not is_valid_number(number, restraints):
|
||||||
number = int(number)
|
|
||||||
for field in restraints:
|
|
||||||
if restraints[field][0][0] <= number <= restraints[field][0][1] or \
|
|
||||||
restraints[field][1][0] <= number <= restraints[field][1][1]:
|
|
||||||
valid = True
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
if not valid:
|
|
||||||
invalid = True
|
invalid = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if invalid:
|
if invalid:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for position, number in enumerate(ticket.split(",")):
|
for position, number in enumerate(ticket):
|
||||||
number = int(number)
|
for field, restraint in restraints.items():
|
||||||
for field in restraints:
|
if not restraint[0][0] <= number <= restraint[0][1] and not restraint[1][0] <= number <= restraint[1][1]:
|
||||||
if not restraints[field][0][0] <= number <= restraints[field][0][1] and \
|
|
||||||
not restraints[field][1][0] <= number <= restraints[field][1][1]:
|
|
||||||
possible_positions[field].remove(position)
|
possible_positions[field].remove(position)
|
||||||
|
|
||||||
single_possibilities = []
|
possible_positions = get_single_possible_positions(possible_positions)
|
||||||
while 1:
|
|
||||||
all_done = True
|
|
||||||
for field, possibilities in possible_positions.items():
|
|
||||||
possible_position = possibilities[0]
|
|
||||||
if len(possibilities) == 1 and possible_position not in single_possibilities:
|
|
||||||
all_done = False
|
|
||||||
single_possibilities.append(possible_position)
|
|
||||||
for check_field in possible_positions:
|
|
||||||
try:
|
|
||||||
if len(possible_positions[check_field]) > 1:
|
|
||||||
possible_positions[check_field].remove(possible_position)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if all_done:
|
|
||||||
break
|
|
||||||
|
|
||||||
answer = 1
|
answer = 1
|
||||||
my_ticket = [int(x) for x in my_ticket.split(",")]
|
|
||||||
for field in restraints:
|
for field in restraints:
|
||||||
if field.startswith('departure'):
|
if field.startswith('departure'):
|
||||||
answer *= my_ticket[possible_positions[field][0]]
|
answer *= my_ticket[possible_positions[field][0]]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user