def countonly(zdelta): largestenclosing={zdelta[0]:set([zdelta[0]])} count = 1 n = len(zdelta) for delta_i in zdelta[1:n-1]: Left = largestenclosing.get( ( (delta_i-1) % n),set([]) ) Right = largestenclosing.get( ( (delta_i+1) % n),set([]) ) if Left or Right: newlargest = set([delta_i]).union(Right).union(Left) largestenclosing[delta_i]=newlargest for delta_j in newlargest: largestenclosing[delta_j] = newlargest if Left and Right: count*=choose(len(Right)+len(Left),len(Right)) else: largestenclosing[delta_i]=set([delta_i]) return count def cycCount(data): return countonly(zdeltaof(data)) def deltaof(li): decorated = zip(li,range(1,len(li)+1)) decorated.sort() decorated.reverse() return [d[1] for d in decorated] def zdeltaof(li): """descent vector with numbering from zero """ decorated = zip(li,range(len(li))) decorated.sort() decorated.reverse() return [d[1] for d in decorated] fac=lambda n: n<=0 or reduce(lambda a,b: long(a)*long(b),xrange(1,n+1)) # n*(n-1)* ... *(n-k+1) def facto(n,k): if k==0: return 1 return(reduce(lambda a,b: long(a)*long(b),xrange(n-k+1,n+1))) def choose(n,k): return(facto(n,k)/fac(k))