aboutsummaryrefslogtreecommitdiff
path: root/2025/08/puzzles.py
blob: 086baca5b25719809bb6fbcc883aced4d5e59495 (plain) (blame)
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()