import math from math import floor, sqrt from itertools import chain D = 4000.0 import math def dist(p,q): return sqrt(sum((x-y)**2 for x,y in zip(p,q))) def solve(input, limit, D=D): points = [] for line in open(input): x,y,z = map(int,line.split(',')) points.append((x,y,z)) def shrink(p): x,y,z = p return floor(x/D), floor(y/D), floor(z/D) m = {} for p in points: q = shrink(p) m.setdefault(q,[]).append(p) def nearest(p): mindist = float('inf') minpoint = p for r in near(shrink(p)): for n in m.get(r,[]): if n != p: d = dist(p,n) if d < mindist: mindist = d minpoint = n return minpoint #for p in points: # q = shrink(p) # print(p, nearest(p), list(chain(*[m.get(x,[]) for x in near(q)]))) pairs = [] for p in points: q = nearest(p) if p != q: d = dist(p,q) pairs.append((d,p,q)) pairs.sort() print(len(pairs)) print(*pairs[:10], sep='\n') def near(q): x,y,z = q for dx in (-1,0,+1): for dy in (-1,0,+1): for dz in (-1,0,+1): #if not (dx==dy==dz==0): yield x+dx,y+dy,z+dz solve("sample", 10, D=350) solve("input", 10, D=8000)