-
Notifications
You must be signed in to change notification settings - Fork 0
/
23.py
72 lines (61 loc) · 1.94 KB
/
23.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
# pylint: skip-file
# mypy: ignore-errors
# flake8: noqa
from collections import defaultdict
input_value = open("23.txt", "r").read()
lines = input_value.split("\n")
edges = set()
adjacency = defaultdict(set)
for line in lines:
edge = tuple(sorted(line.split("-")))
edges.add(edge)
(start, end) = edge
adjacency[start].add(end)
adjacency[end].add(start)
triples = set()
for edge in edges:
(start, end) = edge
mutuals = (adjacency[start] & adjacency[end]).difference({start, end})
for mutual in mutuals:
triples.add(tuple(sorted([start, end, mutual])))
count_target = 0
for triple in triples:
for machine in triple:
if machine[0] == "t":
count_target += 1
break
# Part 1:
print(count_target)
def find_largest_party_for_machine(adjacency, machine):
seen_states = set()
stack = [(machine, {machine})]
largest_set = set()
while stack:
(current, current_set) = stack.pop()
if current in seen_states:
continue
seen_states.add(current)
if len(current_set) > len(largest_set):
largest_set = current_set
for neighbor in adjacency[current]:
if neighbor in current_set:
continue
member_not_found = False
for member in current_set:
desired_edge = tuple((min(member, neighbor), max(member, neighbor)))
if desired_edge not in edges:
member_not_found = True
break
if member_not_found:
continue
stack.append((neighbor, current_set | {neighbor}))
return largest_set
i = 0
largest_party = set()
for machine in adjacency:
largest_party_for_machine = find_largest_party_for_machine(adjacency, machine)
if len(largest_party_for_machine) > len(largest_party):
largest_party = largest_party_for_machine
i += 1
# Part 2:
print(",".join(sorted(largest_party)))