Problem:
Spiral Footrace Let us enjoy extraordinary footraces at an athletic field.
Before starting the race, small flags representing checkpoints are set up
at random on the field. Every runner has to pass all the checkpoints one by
one in the spiral order specified below.
The starting point is the southwest corner of the athletic field. At the starting point, runners are facing north.
During the race, they run clockwise in a spiral passing
every checkpoint as illustrated in the following figure.
When moving from one flag to the next, they take a straight path.
This means that the course of a race is always piecewise linear.   Upon arriving at some flag, a runner has to determine the next flag
among those that are not yet visited.
That flag shall be the one at the smallest angle to the right of the direction
that the runner is facing. When more than two flags are on the same straight
line, the runner visits the nearest flag first.
The goal position is the place of the last visited flag. Your job is to write a program that calculates the length of the course from
the starting point to the goal, supposing that the course consists of
line segments connected by flags.
The position of each flag is given by a coordinate pair
( x i , y i ), which is limited
to the first quadrant. The starting point is fixed to the origin (0, 0) where a
flag is always set up. Input The input contains multiple data sets, each representing a collection of
flag positions for a footrace.  A data set is given in the following
format.  n   x 1  y 1   x 2  y 2  ...  x n  y n   Here, n is the number of flag positions (1 <= n <= 400).
The position of the i -th flag is given by
( x i , y i ), where x i and y i are integers
in meter between 0 and 500 inclusive. 
There may be white spaces (blanks and/or tabs) before, in between, or after x i and y i .
Once a certain
coordinate pair ( x i , y i ) is given,
the same one will not appear later in the data set, and the origin (0, 0)
will not appear either. A data set beginning with n = 0 indicates end of the input. Output For each data set, your program should output the length of the running course
in meter. Each length should appear on a separate line, with
one digit to the right of the decimal point, after rounding it to one
decimal place. Sample Input 8
   60  70
   20  40
   50  50
   70  10
   10  70
   80  90
   70  50
  100  50
5
   60  50
    0  80
   60  20
   10  20
   60  80
0 Output for the Sample Input 388.9
250.0

Solution (Python):
def main():
    while True:
        N = input()    
        if N == 0:
            break
        points = [Vector(map(int, raw_input().split())) for _ in xrange(N)]
        seq = [Vector([0, -1]), Vector([0, 0])]
        while len(points) != 0:
            pre = seq[-1] - seq[-2]
            points.sort(key=lambda x: abs(x-seq[-1]), reverse=True)
            
            points.sort(key=lambda x: (x-seq[-1]).norm() * pre.norm())
            
            p = map(lambda x: (x-seq[-1]).norm() * pre.norm(), points)
            
            
            seq += [points.pop()]
        print round(sum(abs(v2 - v1) for v1, v2 in zip(seq[1:], seq[2:])), 1)

class Vector(tuple):

    def __neg__(self):
        return Vector([-x for x in self])

    def __abs__(self):
        return sum(x ** 2 for x in self) ** 0.5

    def __add__(self, v):
        if len(self) != len(v):
            raise ValueError, "Same dimension is required."
        return Vector([x1 + x2 for x1, x2 in zip(self, v)])

    def __sub__(self, v):
        return self.__add__(-v)
    
    def norm(self):
        a = self.__abs__()
        return Vector([x / a for x in self])

    def __mul__(self,  v):
        """dot product"""
        if len(self) != len(v):
            raise ValueError, "Same dimension is required."
        
        return round(sum(x1 * x2 for x1, x2 in zip(self, v)), 14)

if __name__ == "__main__":
    main()

Solution (Python):
def main():
    while True:
        N = input()    
        if N == 0:
            break
        points = [Vector(map(int, raw_input().split())) for _ in xrange(N)]
        seq = [Vector([0, -1]), Vector([0, 0])]
        while len(points) != 0:
            pre = seq[-1] - seq[-2]
            points.sort(key=lambda x: abs(x-seq[-1]), reverse=True)
            points.sort(key=lambda x: (x-seq[-1]).norm() * pre.norm())
            p = map(lambda x: (x-seq[-1]).norm() * pre.norm(), points)
            seq += [points.pop()]
        print round(sum(abs(v2 - v1) for v1, v2 in zip(seq[1:], seq[2:])), 1)

class Vector(tuple):

    def __neg__(self):
        return Vector([-x for x in self])

    def __abs__(self):
        return sum(x ** 2 for x in self) ** 0.5

    def __add__(self, v):
        if len(self) != len(v):
            raise ValueError, "Same dimension is required."
        return Vector([x1 + x2 for x1, x2 in zip(self, v)])

    def __sub__(self, v):
        return self.__add__(-v)
    
    def norm(self):
        a = self.__abs__()
        return Vector([x / a for x in self])

    def __mul__(self,  v):
        """dot product"""
        if len(self) != len(v):
            raise ValueError, "Same dimension is required."
        
        return round(sum(x1 * x2 for x1, x2 in zip(self, v)), 14)

if __name__ == "__main__":
    main()

Solution (Python):
def main():
    while True:
        N = input()    
        if N == 0:
            break
        points = [Vector(map(int, raw_input().split())) for _ in xrange(N)]
        seq = [Vector([0, -1]), Vector([0, 0])]
        while len(points) != 0:
            pre = seq[-1] - seq[-2]
            points.sort(key=lambda x: abs(x-seq[-1]), reverse=True)
            points.sort(key=lambda x: (x-seq[-1]).norm() * pre.norm())
            seq += [points.pop()]
        print round(sum(abs(v2 - v1) for v1, v2 in zip(seq[1:], seq[2:])), 1)

class Vector(tuple):

    def __neg__(self):
        return Vector([-x for x in self])

    def __abs__(self):
        return sum(x ** 2 for x in self) ** 0.5

    def __add__(self, v):
        if len(self) != len(v):
            raise ValueError, "Same dimension is required."
        return Vector([x1 + x2 for x1, x2 in zip(self, v)])

    def __sub__(self, v):
        return self.__add__(-v)
    
    def norm(self):
        a = self.__abs__()
        return Vector([x / a for x in self])

    def __mul__(self,  v):
        """dot product"""
        if len(self) != len(v):
            raise ValueError, "Same dimension is required."
        return round(sum(x1 * x2 for x1, x2 in zip(self, v)), 14)

if __name__ == "__main__":
    main()

Solution (Python):
import math

def getangle(pointstart,pointend):
    [sx,sy]=pointstart
    [ex,ey]=pointend
    return math.atan2(ey-sy,ex-sx)
    
def getdistance(pointstart,pointend):
    [sx,sy]=pointstart
    [ex,ey]=pointend
    return math.sqrt((ex-sx)**2+(ey-sy)**2)

while(1):
    n=int(raw_input())
    if n==0:
        break
    else:
        pointsnotyet=[]
        for i in range(n):
            pointsnotyet.append([int(x) for x in raw_input().split()])
        pointstart=[0,0]
        angle=math.pi/2
        ans=0
        for i in range(n):
            pointangle=getangle(pointstart,pointsnotyet[0])
            diff=-pointangle+angle
            if diff<0:
                diff+=math.pi*2
            candidateangle=diff
            candidatedistance=getdistance(pointstart,pointsnotyet[0])
            candidateindex=0
            for j in range(1,len(pointsnotyet)):
                pointangle=getangle(pointstart,pointsnotyet[j])
                pointdistance=getdistance(pointstart,pointsnotyet[j])
                diff=-pointangle+angle
                if diff<0:
                    diff+=math.pi*2
                if diff<candidateangle:
                    candidateangle=diff
                    candidatedistance=pointdistance
                    candidateindex=j
                elif diff==candidateangle and pointdistance<candidatedistance:
                    candidateangle=diff
                    candidatedistance=pointdistance
                    candidateindex=j
            pointend=pointsnotyet.pop(candidateindex)
            ans+=getdistance(pointstart,pointend)
            angle=getangle(pointstart,pointend)
            pointstart=pointend
        print round(ans,1)