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

Source: codewars | Difficulty: EASY
Tags: String algorithms

Fundamentals

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)) ** 0.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):
	return ''.join((msg[n * (2 * n - 3):2 * n * (n - 1)] for n in range(int((3 + (9 + 8 * len(msg)) ** 0.5) / 4), 1, -1)))