## Task

You will receive a string consisting of lowercase letters, uppercase letters and digits as input. Your task is to return this string as blocks separated by dashes (`"-"`). The elements of a block should be sorted with respect to the hierarchy listed below, and each block cannot contain multiple instances of the same character. Elements should be put into the first suitable block.

The hierarchy is:
1. lowercase letters (`a - z`), in alphabetical order
2. uppercase letters (`A - Z`), in alphabetical order
3. digits (`0 - 9`), in ascending order

## Examples

* `"21AxBz" -> "xzAB12"` - since input does not contain repeating characters, you only need 1 block
* `"abacad" -> "abcd-a-a"` - character "a" repeats 3 times, thus 3 blocks are needed
* `"" -> ""` - an empty input should result in an empty output
* `"hbh420sUUW222IWOxndjn93cdop69NICEep832" -> "bcdehjnopsxCEINOUW0234689-dhnpIUW239-2-2-2"` - a more sophisticated example

Good luck!

Source: codewars | Difficulty: EASY
Tags: String algorithms

Sorting

Starter code: def blocks(s):
	

Solutions:
from collections import Counter

def blocks(s):
	sort = lambda c: (c.isdigit(), c.isupper(), c)
	(answer, counter) = ([], Counter(s))
	while counter:
		block = ''.join(sorted(counter, key=sort))
		answer.append(block)
		counter = counter - Counter(block)
	return '-'.join(answer)


from collections import Counter
from itertools import zip_longest

def blocks(s):
	return '-'.join(map(sortAndJoin, zip_longest(*blocker(s), fillvalue='')))

def sortAndJoin(lst):
	return ''.join(sorted(lst, key=blockKeyer))

def blockKeyer(c):
	return (c.isdigit(), c.isupper(), c)

def blocker(s):
	return (c * n for (c, n) in Counter(s).items())


from string import ascii_letters, digits
from collections import Counter
ALPHABET = ascii_letters + digits
C_ALPHABET = Counter(ALPHABET)

def blocks(s):
	d = Counter(ALPHABET + s) - C_ALPHABET
	return '-'.join((''.join((x for x in d if d[x] > i)) for i in range(max(d.values(), default=0))))


from collections import Counter as C
from string import ascii_lowercase as l, digits as d

def blocks(s):
	if not s:
		return ''
	char = sorted(C(s).items(), key=lambda x: (l + l.upper() + d).index(x[0]))
	li = [''] * max(char, key=lambda x: x[1])[1]
	for (i, j) in char:
		for pos in range(j):
			li[pos] += i
	return '-'.join(li)


from collections import Counter
sort_group = lambda c: (c.isdecimal(), c.isupper(), c.islower(), c)

def blocks(stg):
	(groups, count) = ([], Counter(stg))
	while count:
		groups.append(''.join(sorted(list(count.keys()), key=sort_group)))
		count -= Counter(list(count.keys()))
	return '-'.join(groups)


from collections import Counter

def blocks(s):
	stg = sorted(sorted(set(s)), key=lambda x: (x.isdigit(), x.isupper()))
	doc = Counter(s)
	ret = ''
	while max(doc.values(), default=0) > 0:
		for e in stg:
			if doc[e] > 0:
				ret += e
			doc[e] -= 1
		ret += '-'
	return ret[:-1]


from collections import Counter
from string import ascii_letters, digits

def blocks(s):
	cnt = Counter(sorted(s, key=(ascii_letters + digits).index))
	res = []
	while cnt:
		res.append(''.join(cnt.keys()))
		cnt = {k: v - 1 for (k, v) in cnt.items() if v > 1}
	return '-'.join(res)


def blocks(s):
	(switch, ret) = ([lambda e: e.islower(), lambda e: e.isupper(), lambda e: e.isdigit()], '')
	for lm in switch:
		ret += ''.join([e for e in sorted(s) if lm(e)])
	return ''.join(box(ret))

def box(blok):
	if blok:
		ret = [''] * blok.count(max(blok, key=blok.count))
		for e in blok:
			for i in range(blok.count(e)):
				ret[i] += ['', e][e not in ret[i]]
		return '-'.join(ret)
	return blok


from string import ascii_letters as let, digits as dig

def blocks(s):
	if s:
		Max = max(map(s.count, s))
		bs = [''.join(sorted([c for c in set(s) if s.count(c) >= n + 1], key=(let + dig).find)) for n in range(Max)]
		return '-'.join(bs)
	else:
		return ''


from itertools import groupby, zip_longest

def blocks(s):
	groups = groupby(sorted(s, key=lambda c: (c.isdigit(), c.isupper(), c)))
	blocks = zip_longest(*(list(b) for (_, b) in groups), fillvalue='')
	return '-'.join((''.join(b) for b in blocks))