defclosest_pair(points): defdistance(p1, p2): return ((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) ** 0.5 deffind_closest_util(points_sorted_by_x, points_sorted_by_y): iflen(points_sorted_by_x) <= 3: return naive_closest_pair(points_sorted_by_x) mid = len(points_sorted_by_x) // 2 midpoint = points_sorted_by_x[mid] left_y = [p for p in points_sorted_by_y if p[0] <= midpoint[0]] right_y = [p for p in points_sorted_by_y if p[0] > midpoint[0]] (p1, p2, left_dist) = find_closest_util(points_sorted_by_x[:mid], left_y) (p3, p4, right_dist) = find_closest_util(points_sorted_by_x[mid:], right_y) min_dist = min(left_dist, right_dist) closest_pair = (p1, p2) if left_dist < right_dist else (p3, p4)
in_strip = [p for p in points_sorted_by_y ifabs(p[0] - midpoint[0]) < min_dist]
for i inrange(len(in_strip)): for j inrange(i + 1, len(in_strip)): if (in_strip[j][1] - in_strip[i][1]) < min_dist: d = distance(in_strip[i], in_strip[j]) if d < min_dist: min_dist = d closest_pair = (in_strip[i], in_strip[j]) else: break