-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday16.py
134 lines (107 loc) · 3.75 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
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3
import pytest
import re
input_list = []
with open('day16.txt', 'r') as f:
strings = f.read().splitlines()
for item in strings:
if item:
input_list.append(item)
rules = input_list[:input_list.index("your ticket:")]
nearby_tickets = input_list[input_list.index("nearby tickets:")+1:]
my_ticket = input_list[input_list.index("your ticket:")+1:input_list.index("nearby tickets:")]
def part_one(rules, tickets):
range_strings = []
for rule in rules:
parts = rule.split(" ")
RANGE_RE = r"[0-9]+-[0-9]+"
for part in parts:
if re.match(RANGE_RE, part):
range_strings.append(part)
valid_nums = []
for r in range_strings:
low_bound = int(r.split("-")[0])
hi_bound = int(r.split("-")[1]) + 1
valid_nums += list(range(low_bound, hi_bound))
valid_nums = sorted(set(valid_nums))
invalid_sum = 0
valid_tickets = []
for ticket in tickets:
valid_ticket = True
for val in ticket.split(","):
if int(val) not in valid_nums:
invalid_sum += int(val)
valid_ticket = False
if valid_ticket:
valid_tickets.append(ticket)
print("Part 1")
print(invalid_sum)
print(len(tickets))
print(len(valid_tickets))
return valid_tickets
@pytest.mark.parametrize("rules, tickets, my_ticket", [
(["class: 0-1 or 4-19",
"row: 0-5 or 8-19",
"seat: 0-13 or 16-19"], ["3,9,18", "15,1,5", "5,14,9"], ["11,12,13"]),
])
def test_part_two(rules, tickets, my_ticket):
mapping = part_two(rules, tickets, my_ticket)
assert mapping['row'] == 0
assert mapping['class'] == 1
assert mapping['seat'] == 2
def part_two(rules, valid_tickets, my_ticket):
rules_dict = dict()
for rule in rules:
field = rule.split(":")[0]
valid_nums = []
parts = rule.split(" ")
RANGE_RE = r"[0-9]+-[0-9]+"
for part in parts:
if re.match(RANGE_RE, part):
low_bound = int(part.split("-")[0])
hi_bound = int(part.split("-")[1]) + 1
valid_nums += list(range(low_bound, hi_bound))
rules_dict[field] = sorted(set(valid_nums))
tickets = []
for t in valid_tickets:
tickets.append(t.split(","))
print(len(tickets))
print(tickets[0])
mapping = {f: 0 for f in rules_dict}
indexes = []
for idx in range(len(tickets[0])):
print(idx)
print(tickets[0][idx])
indexes.append([int(r[idx]) for r in tickets])
print(rules_dict)
print(tickets)
print(indexes)
assigned = []
while len(assigned) < len(rules_dict):
for field in rules_dict:
valid = []
for idx, nums in enumerate(indexes):
all_there = all(item in rules_dict[field] for item in nums)
if all_there and (idx not in assigned):
print(idx, nums)
print(rules_dict[field])
valid.append(idx)
print(valid)
if len(valid) == 1:
mapping[field] = valid[0]
assigned.append(valid[0])
print(mapping)
print(len(rules_dict))
print("assigned: ", assigned, len(assigned))
# final calculation
departure_idxs = [mapping[x] for x in mapping if x.startswith('departure')]
print(departure_idxs)
product = 1
for idx in departure_idxs:
product *= int(my_ticket[0].split(",")[idx])
print("Part 2: ", product)
return mapping
if __name__ == "__main__":
valid_tickets = part_one(rules, nearby_tickets)
print(my_ticket)
part_two(rules, valid_tickets, my_ticket)