summaryrefslogtreecommitdiffstats
path: root/11.py
blob: 645c6c7bcb523dc96ffccf9b7bd3a2573bf2e19e (plain)
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
# pyright: strict
from itertools import accumulate, combinations
from sys import stdin


def offsets(length: int, present: set[int]) -> list[int]:
    return list(accumulate(1 if i not in present else 0 for i in range(length)))


def solve(
    points: set[tuple[int, int]],
    x_offsets: list[int],
    y_offsets: list[int],
    expansion: int = 2,
) -> int:
    def offset(p: tuple[int, int]) -> tuple[int, int]:
        return (
            p[0] + x_offsets[p[0]] * (expansion - 1),
            p[1] + y_offsets[p[1]] * (expansion - 1),
        )

    def manhattan_distance(a: tuple[int, int], b: tuple[int, int]) -> int:
        return abs(a[0] - b[0]) + abs(a[1] - b[1])

    return sum(
        manhattan_distance(offset(a), offset(b)) for a, b in combinations(points, 2)
    )


points = {(x, y) for y, l in enumerate(stdin) for x, c in enumerate(l) if c == "#"}

x_present, y_present = set(p[0] for p in points), set(p[1] for p in points)
width, height = max(x for x in x_present) + 1, max(y for y in y_present) + 1
x_offsets = offsets(width, x_present)
y_offsets = offsets(height, y_present)

print(solve(points, x_offsets, y_offsets))
print(solve(points, x_offsets, y_offsets, 1000000))