points=[0.0,0.1,0.2,0.5,2.0]
eps,min_samples=0.31,3
neighbors=[[j for j,y in enumerate(points) if abs(x-y)<=eps] for x in points]
# This contract includes the point itself in min_samples.
core={i for i,ns in enumerate(neighbors) if len(ns)>=min_samples}
labels=[-1]*len(points)
cluster=0
for start in sorted(core):
    if labels[start]!=-1:
        continue
    stack=[start]
    labels[start]=cluster
    while stack:
        i=stack.pop()
        for j in neighbors[i]:
            if j in core and labels[j]==-1:
                labels[j]=cluster
                stack.append(j)
    cluster+=1
for i in range(len(points)):
    if i not in core:
        adjacent=sorted({labels[j] for j in neighbors[i] if j in core})
        if adjacent:
            labels[i]=adjacent[0]
roles=['core' if i in core else 'border' if labels[i]>=0 else 'noise'
       for i in range(len(points))]
print('neighbors',neighbors)
print('labels',labels,'roles',roles)
assert labels==[0,0,0,0,-1]
assert roles==['core','core','core','border','noise']
