Skip to content

Commit 781bd0e

Browse files
authored
Create Rubidium2018.py
1 parent ae4758c commit 781bd0e

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

Rubidium2018.py

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# you can write to stdout for debugging purposes, e.g.
2+
# print("this is a debug message")
3+
4+
# you can write to stdout for debugging purposes, e.g.
5+
# print("this is a debug message")
6+
7+
def closest_split_pair(p_x, p_y, delta, best_pair):
8+
ln_x = len(p_x) # store length - quicker
9+
mx_x = p_x[ln_x // 2][0] # select midpoint on x-sorted array
10+
11+
# Create a subarray of points not further than delta from
12+
# midpoint on x-sorted array
13+
14+
s_y = [x for x in p_y if mx_x - delta <= x[0] <= mx_x + delta]
15+
16+
best = delta # assign best value to delta
17+
ln_y = len(s_y) # store length of subarray for quickness
18+
for i in range(ln_y - 1):
19+
for j in range(i+1, min(i + 7, ln_y)):
20+
p, q = s_y[i], s_y[j]
21+
dst = dist(p, q)
22+
if dst < best:
23+
best_pair = p, q
24+
best = dst
25+
return best_pair[0], best_pair[1], best
26+
27+
def dist(p1, p2):
28+
return max(abs(p1[0] - p2[0]), abs(p1[1] - p2[1]))
29+
30+
def brute(ax):
31+
mi = dist(ax[0], ax[1])
32+
p1 = ax[0]
33+
p2 = ax[1]
34+
ln_ax = len(ax)
35+
if ln_ax == 2:
36+
return p1, p2, mi
37+
for i in range(ln_ax-1):
38+
for j in range(i + 1, ln_ax):
39+
if i != 0 and j != 1:
40+
d = dist(ax[i], ax[j])
41+
if d < mi: # Update min_dist and points
42+
mi = d
43+
p1, p2 = ax[i], ax[j]
44+
return p1, p2, mi
45+
46+
def closest_pair(ax, ay):
47+
ln_ax = len(ax) # It's quicker to assign variable
48+
if ln_ax <= 3:
49+
return brute(ax) # A call to bruteforce comparison
50+
mid = ln_ax // 2 # Division without remainder, need int
51+
Qx = ax[:mid] # Two-part split
52+
Rx = ax[mid:]
53+
54+
# Determine midpoint on x-axis
55+
56+
midpoint = ax[mid][0]
57+
Qy = list()
58+
Ry = list()
59+
for x in ay: # split ay into 2 arrays using midpoint
60+
if x[0] <= midpoint:
61+
Qy.append(x)
62+
else:
63+
Ry.append(x)
64+
65+
# Call recursively both arrays after split
66+
67+
(p1, q1, mi1) = closest_pair(Qx, Qy)
68+
(p2, q2, mi2) = closest_pair(Rx, Ry)
69+
70+
# Determine smaller distance between points of 2 arrays
71+
72+
if mi1 <= mi2:
73+
d = mi1
74+
mn = (p1, q1)
75+
else:
76+
d = mi2
77+
mn = (p2, q2)
78+
79+
# Call function to account for points on the boundary
80+
81+
(p3, q3, mi3) = closest_split_pair(ax, ay, d, mn)
82+
83+
# Determine smallest distance for the array
84+
85+
if d <= mi3:
86+
return mn[0], mn[1], d
87+
else:
88+
return p3, q3, mi3
89+
90+
def solution(X, Y):
91+
a = list(zip(X, Y))
92+
ax = sorted(a, key=lambda x: x[0]) # Presorting x-wise
93+
ay = sorted(a, key=lambda x: x[1]) # Presorting y-wise
94+
(x1, y1), (x2, y2), mi = closest_pair(ax, ay) # Recursive D&C function
95+
96+
lo = 0
97+
high = 10 ** 5
98+
while lo < high:
99+
mid = (lo + high + 1) // 2
100+
if abs(x1 - x2) < 2 * mid and abs(y1 - y2) < 2 * mid:
101+
high = mid - 1
102+
else:
103+
lo = mid
104+
return lo

0 commit comments

Comments
 (0)