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
|
#!/usr/bin/python3
import functools
import heapq
import itertools
import math
import operator
type Point = tuple[int, int, int]
type Circuit = set[Point]
def main() -> None:
with open('input', 'r') as f:
boxes = [tuple(map(int, l.split(','))) for l in f.readlines()]
circuits: list[Circuit] = []
pairs = itertools.combinations(boxes, 2)
pairs = iter(sorted(pairs, key=lambda p: math.dist(*p)))
# START PART 1
for p, q in itertools.islice(pairs, 1000):
connect(circuits, p, q)
lens = heapq.nlargest(3, map(len, circuits))
print(functools.reduce(operator.mul, lens))
# END PART 1 START PART 2
while len(circuits) != 1 or len(circuits[0]) != len(boxes):
p, q = next(pairs)
connect(circuits, p, q)
print(p[0] * q[0])
# END PART 2
def connect(circuits: list[Circuit], p: Point, q: Point) -> None:
pc = next((c for c in circuits if p in c), None)
qc = next((c for c in circuits if q in c), None)
match (pc, qc):
case (None, None):
circuits.append({p, q})
case (x, None):
pc.add(q)
case (None, y):
qc.add(p)
case (x, y) if x is not y:
circuits.remove(qc)
pc |= qc
if __name__ == '__main__':
main()
|