/*
分析:
分治法求最近点对。
分治的过程其实就是线段树,一个砍俩,然后合并时候要处理一下。
大一刚刷a+b时不会的题,今儿切掉了,深刻体验到sort的确是qsort
的改进版本额,囧~
其实我挺好奇有多少人和我一样,要期末考试了还是不想预习,还在这儿没心没肺的切水题。。。
2013-01-08
*/
#include"stdio.h"
#include"string.h"
#include"algorithm"
#include"math.h"
#define N 100011
using namespace std;
int n;
struct Point
{
double x,y;
}E[N],Temp[N];
bool cmpx(Point a,Point b) {return a.x<b.x;}
bool cmpy(Point a,Point b) {return a.y<b.y;}
double closest(int l,int r)
{
if(l+1==r) return sqrt((E[l].x-E[r].x)*(E[l].x-E[r].x)+(E[l].y-E[r].y)*(E[l].y-E[r].y));
else if(l+2==r)
{
double a,b,c;
a=(E[l].x-E[r].x)*(E[l].x-E[r].x)+(E[l].y-E[r].y)*(E[l].y-E[r].y);
b=(E[l+1].x-E[r].x)*(E[l+1].x-E[r].x)+(E[l+1].y-E[r].y)*(E[l+1].y-E[r].y);
c=(E[l].x-E[r+1].x)*(E[l].x-E[r+1].x)+(E[l].y-E[r+1].y)*(E[l].y-E[r+1].y);
if(b<a) a=c;
if(c<a) a=c;
return sqrt(a);
}
int i,j,count,mid;
mid=(l+r)>>1;
double a,b,temp,min;
a=closest(l,mid);
b=closest(mid+1,r);
min=a>b?b:a;
for(i=l,count=0;i<=r;i++) if(fabs(E[i].x-E[mid].x)<=min) Temp[count++]=E[i];
sort(Temp,Temp+count,cmpy);
for(i=0;i<count;i++)
for(j=i+1;j<count;j++)
{
a=Temp[j].y-Temp[i].y;
if(a>=min) break;
b=Temp[j].x-Temp[i].x;
temp=sqrt(a*a+b*b);
if(temp<min) min=temp;
}
return min;
}
int main()
{
int i;
while(scanf("%d",&n),n)
{
for(i=0;i<n;i++) scanf("%lf%lf",&E[i].x,&E[i].y);
sort(E,E+n,cmpx);
printf("%.2lf\n",closest(0,n-1)/2);
}
return 0;
}