aoc2025/day08.py
2025-12-08 07:07:18 +01:00

70 lines
1.9 KiB
Python

from tools.aoc import AOCDay
from tools.coordinate import Coordinate
from typing import Any
class Day(AOCDay):
inputs = [
[
(40, "input8_test"),
(140008, "input8"),
],
[
(25272, "input8_test"),
(9253260633, "input8"),
]
]
def parse_input(self) -> tuple[dict[float, Coordinate], dict[Coordinate, int]]:
boxes = [Coordinate(*map(int, line.split(","))) for line in self.getInput()]
dists = {}
for i, box in enumerate(boxes):
for box2 in boxes[i + 1 :]:
dists[box.getDistanceTo(box2)] = (box, box2)
members = {box: i for i, box in enumerate(boxes)}
return dists, members
def solve(self, part2: bool = False) -> int:
dists, members = self.parse_input()
circuits = {i: [box] for box, i in members.items()}
connections_needed = 10 if self.is_test() else 1000
connections_done = 0
last_pair = None
for _, (box0, box1) in sorted(dists.items()):
connections_done += 1
if (not part2 and connections_done > connections_needed) or len(circuits) == 1:
break
if members[box0] == members[box1]:
continue
merger = members[box1]
for box in circuits[merger]:
members[box] = members[box0]
circuits[members[box0]].append(box)
del circuits[merger]
last_pair = (box0, box1)
if part2:
return last_pair[0].x * last_pair[1].x
else:
ans = 1
for _, v in sorted(circuits.items(), key=lambda k: len(k[1]), reverse=True)[:3]:
ans *= len(v)
return ans
def part1(self) -> Any:
return self.solve()
def part2(self) -> Any:
return self.solve(part2=True)
if __name__ == '__main__':
day = Day(2025, 8)
day.run(verbose=True)