-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path16.py
60 lines (46 loc) · 1.52 KB
/
16.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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)