-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday16.py
122 lines (82 loc) · 2.68 KB
/
day16.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from collections import defaultdict
attrs = dict()
your_ticket = []
nearby_tickets = []
with open("data/day16.txt") as f:
data = f.read().split("\n\n")
for item in data[0].split("\n"):
key, val = item.split(": ", 1)
ranges = tuple(map(lambda s: tuple(map(int, s.split("-"))), val.split(" or ")))
attrs[key] = ranges
your_ticket = list(map(int, data[1].split("\n")[1].split(",")))
for item in data[2].split("\n", 1)[1].split("\n"):
if len(item) > 0:
nearby_tickets.append(list(map(int, item.split(","))))
print("ranges: ", attrs)
print("your ticket: ", your_ticket)
print("nearby tickets: ", nearby_tickets)
def is_valid(num):
for a in attrs.values():
for r in a:
if num >= r[0] and num <= r[1]:
return True
return False
def task1():
invalid = []
for item in nearby_tickets:
for num in item:
if not is_valid(num):
invalid.append(num)
print("answer: ", sum(invalid))
def is_valid_ticket(ticket):
return False not in list(map(is_valid, ticket))
def can_be_attr(values, ranges):
for v in values:
is_valid = False
for r in ranges:
if r[0] <= v <= r[1]:
is_valid = True
break
if not is_valid:
return False
return True
def get_attr(values):
result = set()
for key, ranges in attrs.items():
if can_be_attr(values, ranges):
result.add(key)
return result
def has_multiple_options(columns):
return len(list(filter(lambda s: len(s) > 1, columns.values()))) > 0
def task2():
valid = list(filter(is_valid_ticket, nearby_tickets))
columns = dict()
for i in range(len(valid[0])):
values = set()
for ticket in valid:
values.add(ticket[i])
columns[i] = get_attr(values)
taken = set()
while has_multiple_options(columns):
# find all the ones where only 1 option exists
for key, value in columns.items():
if len(value) == 1:
taken.add(list(value)[0])
updated_columns = dict()
for key, value in columns.items():
if len(value) > 1:
new_values = value.difference(taken)
else:
new_values = value
updated_columns[key] = new_values
columns = updated_columns
answer = 1
for key, value in updated_columns.items():
val = list(value)[0]
print(val)
if val.startswith('departure'):
answer *= your_ticket[key]
print('answer2: ', answer)
print(columns)
task1()
task2()