import math def dist(p1, p2): return math.sqrt(((p2[1]-p1[1])**2)+((p2[0]-p1[0])**2)) def closest_brute_force(P): min_dist = float("inf") p1 = None p2 = None for i in range(len(P)): for j in range(i+1, len(P)): d = dist(P[i], P[j]) if d < min_dist: min_dist = d p1 = P[i] p2 = P[j] return p1, p2, min_dist def rec(X, Y): n = len(X) if n <= 3: return closest_brute_force(X) else: midpoint = x[n//2] X_l = x[:n//2] X_r = x[n//2:] Y_l = [] Y_r = [] for point in Y: Y_l.append(point) if (point[0] <= midpoint[0]) else Y_r.append(point) (p1_l, p2_l, d_l) = rec(X_l, Y_l) (p1_r, p2_r, d_r) = rec(X_r, Y_r) (p1, p2, d) = (p1_l, p2_l, d_l) if (d_l < d_r) else (p1_r, p2_r, d_r) in_band = [point for point in y if midpoint[0]-d < point[0] < midpoint[0]+d] for i in range(len(in_band)): for j in range(i+1, min(i+7, len(in_band))): d = dist(in_band[i], in_band[j]) if d < d: print(in_band[i], in_band[j]) (p1, p2, d) = (in_band[i], in_band[j], d) return p1, p2, d def closest(P): X = sorted(P, key=lambda point: point[0]) Y = sorted(P, key=lambda point: point[1]) return rec(X, Y)