# Task

Write a function `deNico`/`de_nico()` that accepts two parameters:
- `key`/`$key` - string consists of unique letters and digits
- `message`/`$message` - string with encoded message 

and decodes the `message` using the `key`.  

First create a numeric key basing on the provided `key` by assigning each letter position in which it is located after setting the letters from `key` in an alphabetical order.

For example, for the key `crazy` we will get `23154` because of `acryz` (sorted letters from the key).  
Let's decode  `cseerntiofarmit on  ` using our `crazy` key.

```
1 2 3 4 5
---------
c s e e r
n t i o f
a r m i t
  o n   
```

After using the key:
```
2 3 1 5 4
---------
s e c r e
t i n f o
r m a t i
o n
```

# Notes 

- The `message` is never shorter than the `key`.
- Don't forget to remove trailing whitespace after decoding the message

# Examples

Check the test cases for more examples.

# Related Kata

[Basic Nico - encode](https://www.codewars.com/kata/5968bb83c307f0bb86000015)

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Starter code: def de_nico(key,msg):
	

Solutions:
def de_nico(key, msg):
	(ll, order, s) = (len(key), [sorted(key).index(c) for c in key], '')
	while msg:
		(s, msg) = (s + ''.join((msg[i] for i in order if i < len(msg))), msg[ll:])
	return s.strip()


def de_nico(key, msg):
	decoder = []
	for letter in key:
		decoder.append(sorted(key).index(letter))
	msg_segs = [msg[i:i + len(key)] for i in range(0, len(msg), len(key))]
	enum_segs = []
	for seg in msg_segs:
		enum_segs.append(dict(zip(range(len(seg)), seg)))
	decoded_msg = []
	for seg in enum_segs:
		for codon in decoder:
			try:
				decoded_msg.append(seg[codon])
			except KeyError:
				continue
	return ''.join(decoded_msg).rstrip()


from operator import itemgetter

def de_nico(key, msg):
	(decryptkey, _) = zip(*sorted(zip(range(1, len(key) + 1), key), key=itemgetter(1)))
	decryptkey = ''.join((str(x) for x in decryptkey))
	chunksize = len(decryptkey)
	chunks = [msg[y - chunksize:y] for y in range(chunksize, len(msg) + chunksize, chunksize)]
	for (i, chunk) in enumerate(chunks):
		(chunkSorted, _) = zip(*sorted(zip(chunk, decryptkey), key=itemgetter(1)))
		chunks[i] = ''.join(chunkSorted)
	return ''.join(chunks).rstrip()


import itertools

def de_nico(key, msg):
	pack = [list(range(len(key)))] + list((list(msg[i:i + len(key)]) for i in range(0, len(msg), len(key))))
	sor = [sorted(key).index(i) for i in key]
	sorting = sorted(itertools.zip_longest(*pack, fillvalue=''), key=lambda col: sor.index(col[0]))
	return ''.join([''.join(j) for (i, j) in enumerate(itertools.zip_longest(*sorting, fillvalue=' ')) if i > 0]).strip(' ')


def de_nico(key, msg):
	result = ''
	counter = -1
	while len(result) < len(msg):
		counter += 1
		for i in [sorted(key).index(c) for c in key]:
			try:
				result += msg[i + counter * len(key)]
			except:
				continue
	return result.strip()


def de_nico(key, msg):
	sorted_key = sorted(key)
	num_key = []
	for chr in key:
		num_key.append(sorted_key.index(chr))
	result = ''
	start = 0
	end = len(key)
	while start < len(msg):
		chunk = msg[start:end]
		for index in num_key:
			if index < len(chunk):
				result += chunk[index]
		start = end
		end += len(key)
	return result.strip()


de_nico = lambda k, m: (lambda k: ''.join(((lambda g: ''.join((g[p] for p in k if p < len(g))))(m[i * len(k):(i + 1) * len(k)]) for i in range(len(m) // len(k) + 1))).strip())((lambda s: [s.index(l) for l in k])(sorted(k)))


def de_nico(key, msg):
	num_key = ''.join([str(id) for i in key for (id, item) in enumerate(sorted(key), 1) if item == i])
	cut_msg = [msg[i:i + len(num_key)] for i in range(0, len(msg), len(num_key))]
	d_msg = [''.join([item for i in num_key for (id, item) in enumerate(list(x), 1) if id == int(i)]) for x in cut_msg]
	return ''.join(d_msg).rstrip()


from itertools import chain, zip_longest

def de_nico(key, msg):
	columns = [msg[n::len(key)] for n in range(len(key))]
	key = (n for (n, c) in sorted(enumerate(key), key=lambda k: k[1]))
	return ''.join(chain(*zip_longest(*sorted(columns, key=lambda k: next(key)), fillvalue=''))).strip()


from itertools import cycle

def de_nico(key, msg):
	code = tuple((sorted(key).index(k) + 1 for k in key))
	code_cycle = cycle(code)
	key_cycle = cycle(range(1, len(key) + 1))
	msg_encrypted = [(k, next(key_cycle)) for k in msg]
	result = []
	while msg_encrypted:
		try:
			index = next(code_cycle)
			found = next((p for p in msg_encrypted if p[1] == index))
			msg_encrypted.remove(found)
			result.append(found[0])
		except StopIteration:
			pass
	return ''.join(result).strip()