# 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:

```      
                                                      3 
                              p                     2   4
            g               o   q                 1
  b       f   h           n       r             z 
a   c   e       i       m          s          y
      d           j   l             t       x
                    k                 u   w 
                                        v


```
The next top is always 1 character higher than the previous one. 
For the above example, the solution for the `abcdefghijklmnopqrstuvwxyz1234` input string is `3pgb`.

- When the `msg` string is empty, return an empty string.
- The input strings may be very long. Make sure your solution has good performance.

Check the test cases for more samples.

# **Note** for C++

Do not post an issue in my solution without checking if your returned string doesn't have some invisible characters. You read most probably outside of `msg` string.

Difficulty: introductory

Starter code:

def tops(msg):
	

Solutions:
def tops(msg):
    i,d,s = 1,5, ''
    while i < len(msg):
        s += msg[i]
        i += d
        d += 4
    return s[::-1]

def tops(msg):
    if len(msg) < 2:
        return ''
    g = 2
    k = ''
    ni = 0
    k += msg[1]
    for i in msg[1:]:
        if ni == g * 2 + 1:
            k += i
            g += 2
            ni = 0
        ni += 1
    return k[::-1]

def tops(msg):
    if not msg: return ''
    n, length = 2, len(msg)
    counter = 0
    s = ''
    while counter+n <= length:
        counter += n
        s += msg[counter-1]
        counter += n-1
        n += 2
    return s[::-1]

def tops(stg):
    l = int((1 + (1 + 8*len(stg))**0.5) / 4)
    return "".join(stg[n * (2*n - 1)] for n in range(l, 0, -1))


from itertools import accumulate, count, takewhile

def indexes():
    it = count(0)
    while True:
        yield next(it) + next(it)
    
def tops(msg):
    n = len(msg)
    return ''.join(msg[i] for i in list(takewhile(lambda i: i < n, accumulate(indexes())))[::-1])

def tops(msg):
    res=''
    top=1
    diff=5
    while top<len(msg):
        res+=msg[top]
        top+=diff
        diff+=4
    return res[::-1]

def tops(msg):
    result, i, offset = '', 1, 5
    while i < len(msg):
        result += msg[i]
        i += offset
        offset += 4
    return result[::-1]

def tops(msg):
  i = 1
  j = 2
  res = []
  
  while i < len(msg):
    res.append(msg[i])
    i += 2*j+1
    j += 2
  
  return ''.join(res)[::-1]

tops=lambda m,n=1: (lambda q: "" if q>len(m) else tops(m,n+1)+m[q])(2*n*n-n)

tops=lambda s:''.join(s[n*(2*n-1)]for n in range(int(((8*len(s)+1)**.5+1)/4),0,-1))