-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchallenge.py
89 lines (65 loc) · 1.9 KB
/
challenge.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import math
import re
def ints(s: str):
return list(map(int, re.findall(r"-?\d+", s))) # thanks mserrano!
def psub(x, y):
if len(x) == 2:
return [x[0] - y[0], x[1] - y[1]]
return [a-b for a, b in zip(x, y)]
def pdist1(x, y=None):
if y is not None:
x = psub(x, y)
if len(x) == 2:
return abs(x[0]) + abs(x[1])
return sum(map(abs, x))
class UnionFind:
# n: int
# parents: List[Optional[int]]
# ranks: List[int]
# num_sets: int
def __init__(self, n: int) -> None:
self.n = n
self.parents = [None] * n
self.ranks = [1] * n
self.num_sets = n
def find(self, i: int) -> int:
p = self.parents[i]
if p is None:
return i
p = self.find(p)
self.parents[i] = p
return p
def in_same_set(self, i: int, j: int) -> bool:
return self.find(i) == self.find(j)
def merge(self, i: int, j: int) -> None:
i = self.find(i)
j = self.find(j)
if i == j:
return
i_rank = self.ranks[i]
j_rank = self.ranks[j]
if i_rank < j_rank:
self.parents[i] = j
elif i_rank > j_rank:
self.parents[j] = i
else:
self.parents[j] = i
self.ranks[i] += 1
self.num_sets -= 1
def main():
# Here begins the actual code for today:
with open("./inputs/challenge.txt") as f:
print("Parsing Data: ")
inp = f.read()
lines = inp.splitlines()
to_i = dict()
uf = UnionFind(len(lines))
for i, line in enumerate(lines):
p = tuple(ints(line))
to_i[p] = i
for point in to_i:
if pdist1(p, point) <= 3:
uf.merge(i, to_i[point])
print(uf.num_sets)
if __name__ == "__main__":
main()