AdventOfCode/Python/2020/16.py

60 lines
1.5 KiB
Python

from lib import *
input = read_input(2020, 16)
def valid(rule, num):
ranges = rule.split(": ")[1].split(" or ")
for r in ranges:
x, y = map(int, r.split("-"))
if x <= num <= y:
return True
return False
rules, mt, nt = map(str.splitlines, input.split("\n\n"))
out = 0
nt.pop(0)
for ticket in nt:
for f in map(int, ticket.split(",")):
for r in rules:
if valid(r, f):
break
else:
out += f
print(out)
rules, mt, nt = map(str.splitlines, input.split("\n\n"))
mt = list(map(int, mt[1].split(",")))
nt = [list(map(int, ticket.split(","))) for ticket in nt[1:]]
nt = [ticket for ticket in nt if all(any(valid(r, f) for r in rules) for f in ticket)]
possible_allocations = [set(range(len(rules))) for i in range(len(rules))]
for ticket in nt:
for field in range(len(rules)):
for rule in range(len(rules)):
if not valid(rules[rule], ticket[field]):
possible_allocations[rule].remove(field)
allocations = [None] * len(rules)
while any(x is None for x in allocations):
for i in range(len(rules)):
if len(possible_allocations[i]) == 1:
j = possible_allocations[i].pop()
allocations[i] = j
for k in range(len(rules)):
if j in possible_allocations[k]:
possible_allocations[k].remove(j)
out = 1
for i, rule in enumerate(rules):
if not rule.startswith("departure"):
continue
j = allocations[i]
out *= mt[j]
print(out)