# Task

Write a function that accepts `msg` string and returns local tops of string from the highest to the lowest.  
The string's tops are from displaying the string in the below way:

```

                                         7891012
                             TUWvXY      6     3
                   ABCDE     S    Z      5
           lmno    z   F     R    1      4
     abc   k  p    v   G     Q    2      3
.34..9 d...j  q....x   H.....P    3......2
125678 efghi  rstuwy   IJKLMNO    45678901

```
The next top is always 1 character higher than the previous one. 
For the above example, the solution for the `123456789abcdefghijklmnopqrstuwyxvzABCDEFGHIJKLMNOPQRSTUWvXYZ123456789012345678910123` input string is `7891012TUWvXYABCDElmnoabc34`. 

- When the `msg` string is empty, return an empty string.
- The input strings may be very long. Make sure your solution has good performance.
- The (.)dots on the sample dispaly of string are only there to help you to understand the pattern  

Check the test cases for more samples.

# Series

- [String tops](https://www.codewars.com/kata/59b7571bbf10a48c75000070)
- [Square string tops](https://www.codewars.com/kata/5aa3e2b0373c2e4b420009af)

Difficulty: introductory

Starter code:

def tops(msg):
	

Solutions:
def tops(msg):
    n = len(msg)
    res,i,j,k = "",2,2,7
    while i < n:
        res = msg[i:i+j] + res
        i,j,k=i+k,j+1,k+4
    return res

def transform(i): return (3*i-4+2*(i-1)*(i-2), i)

def tops(msg):
    iMax = int((3+(9+8*len(msg))**.5) / 4)
    return ''.join( msg[i:i+c] for i,c in map(transform, reversed(range(2,iMax+1))) )

def tops(msg):
    i,l, step, st = 2,2,2, []
    while l<len(msg):
        st.insert(0, msg[l:l+i] )
        step += 3
        l += step + i 
        i += 1
    return ''.join(st)


from math import ceil
from numpy import roots

def gen(msg, i, n):
    while n > 1:
        yield msg[i:i+n]
        n -= 1
        i -= 4*n - 1

def tops(msg):
    number = ceil(roots((2, 5, 2-len(msg)))[1]) + 1
    start = number * (2*number - 3)
    return ''.join(gen(msg, start, number))

from itertools import count

def tops(msg):
    deltas = count(7, 4)
    xs = []
    i, n = 2, 2
    while i < len(msg):
        xs.append(msg[i:i+n])
        i += next(deltas)
        n += 1
    return ''.join(reversed(xs))

def tops(msg):
    if msg:
        step = int(((2 * len(msg) - 1)**0.5 + 3) / 2)
        result = [msg[n*(2*n+1)-1:2*n*(n+1)] for n in range(1, step)]
        return "".join(reversed(result))
    return ""


def tops(s):
    tops, start = [s[2:4]], 2
    while start < len(s):
        l = len(tops[-1])
        start += (l - 1) * 2 + l * 2 + 1
        tops.append(s[start:start + l + 1]) 
    return "".join(tops[::-1])

def tops(msg):
    return "".join(msg[(i*2-1)*(i+1):i*(i+1)*2] for i in range(int(1+(-1+(1+2*len(msg))**0.5)*0.5),0,-1))

def tops(msg):
    r=[]
    for i in range(int(1+(-1+(1+2*len(msg))**0.5)*0.5),0,-1):
        r.append(msg[(i*2-1)*(i+1):i*(i+1)*2])
    return ''.join(r)

def tops(msg):
    return "".join(msg[n*(2*n-3):2*n*(n-1)] for n in range(int((3 + (9 + 8*len(msg))**.5)/4), 1, -1))