# Introduction 

Digital Cypher assigns a unique number to each letter of the alphabet:

```
 a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
```

In the encrypted word we write the corresponding numbers instead of the letters. For example, the word `scout` becomes:

```
 s  c  o  u  t
19  3 15 21 20
```
Then we add to each number a digit from the key (repeated if necessary). For example if the key is `1939`:

```
   s  c  o  u  t
  19  3 15 21 20
 + 1  9  3  9  1
 ---------------
  20 12 18 30 21
  
   m  a  s  t  e  r  p  i  e  c  e
  13  1 19 20  5 18 16  9  5  3  5
+  1  9  3  9  1  9  3  9  1  9  3
  --------------------------------
  14 10 22 29  6 27 19 18  6  12 8
```

# Task

Write a function that accepts a `message` string  and an array of integers `code`. As the result, return the `key` that was used to encrypt the `message`. The `key` has to be shortest of all possible keys that can be used to code the `message`: i.e. when the possible keys are `12` , `1212`, `121212`, your solution should return `12`.

#### Input / Output:

* The `message` is a string containing only lowercase letters.
* The `code` is an array of positive integers.
* The `key` output is a positive integer.

# Examples

```python
find_the_key("scout", [20, 12, 18, 30, 21]) # -->  1939
find_the_key("masterpiece", [14, 10, 22, 29, 6, 27, 19, 18, 6, 12, 8]) # -->  1939
find_the_key("nomoretears", [15, 17, 14, 17, 19, 7, 21, 7, 2, 20, 20]) # -->  12
```

# Digital cypher series
- [Digital cypher vol 1](https://www.codewars.com/kata/592e830e043b99888600002d)
- [Digital cypher vol 2](https://www.codewars.com/kata/592edfda5be407b9640000b2)
- [Digital cypher vol 3 - missing key](https://www.codewars.com/kata/5930d8a4b8c2d9e11500002a)

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Starter code: def find_the_key(message, code):
	

Solutions:
def find_the_key(message, code):
	diffs = ''.join((str(c - ord(m) + 96) for (c, m) in zip(code, message)))
	for size in range(1, len(code) + 1):
		key = diffs[:size]
		if (key * len(code))[:len(code)] == diffs:
			return int(key)


def find_the_key(message, code):
	key = ''.join((str(code[i] + 96 - ord(char)) for (i, char) in enumerate(message)))
	l = len(key)
	for i in range(1, l + 1):
		if (key[:i] * l)[:l] == key:
			return int(key[:i])


find_the_key = lambda s, e: (lambda l, d: min((int(d[:i]) for i in range(l) if (d[:i] * l)[:l] == d)))(len(s), ''.join((str(n - ord(c) + 96) for (c, n) in zip(s, e))))


def find_the_key(message, code):
	r = ''.join((str(a - b) for (a, b) in zip(code, [ord(c) - 96 for c in message])))
	for k in range(1, len(r) + 1):
		if all((c == r[:k][i % k] for (i, c) in enumerate(r))):
			return int(r[:k])


def find_the_key(message, code):
	key = ''.join((str(c - 'abcdefghijklmnopqrstuvwxyz'.index(m) - 1) for (m, c) in zip(message, code)))
	return int(next((key[0:i] for i in range(1, len(key)) if all((key[0:i].startswith(key[j:j + i]) for j in range(i, len(key), i))))))


from string import ascii_lowercase as al

def find_the_key(message, code):
	msg_key = ''.join([str(a - d) for (a, d) in zip(code, [al.index(c) + 1 for c in message])])
	(key, len_msg) = ('', len(msg_key))
	for (i, n) in enumerate(msg_key, 1):
		key += n
		(d, m) = divmod(len_msg, i)
		test_key = key * (d + (m > 0))
		if test_key[:len_msg] == msg_key:
			return int(key)


from string import ascii_lowercase
ns = {x: i for (i, x) in enumerate(ascii_lowercase, 1)}

def short(xs):
	for i in range(1, len(xs)):
		if all((len(set(xs[j::i])) == 1 for j in range(i))):
			return xs[:i]
	return xs

def find_the_key(message, code):
	xs = [a - b for (a, b) in zip(code, map(ns.get, message))]
	return int(''.join(map(str, short(xs))))


def find_the_key(message, code):
	import string
	mapowanie_str_dig = dict(zip(list(string.ascii_lowercase), [x for x in range(1, 27)]))
	m = []
	for s in message:
		m = m + [mapowanie_str_dig[s]]
	delta = [str(abs(code[i] - m[i])) for i in range(0, len(m))]
	for i in range(1, len(delta) + 1):
		n = len(delta) // i
		r = len(delta) % i
		if n * delta[0:i] == delta[0:n * i] and delta[0:r] == delta[n * i:]:
			output = delta[0:i]
			break
	return int(''.join(output))


from string import ascii_lowercase as letters

def find_the_key(message, code):
	diff = [e - letters.index(c) - 1 for (e, c) in zip(code, message)]
	for n in range(1, len(diff)):
		ok = True
		for k in range(n, len(diff), n):
			if diff[k:k + n] != diff[:min(n, len(diff) - k)]:
				ok = False
				break
		if ok:
			diff = diff[:n]
			break
	key = 0
	for k in diff:
		key = key * 10 + k
	return key


def find_the_key(msg, code):
	from itertools import cycle
	msg = [ord(i) - 96 for i in msg]
	keys = [code[i] - msg[i] for i in range(len(code))]
	key = ''.join([str(i) for i in keys])
	i = 1
	while True:
		a = cycle(key[:i])
		if [_ + int(next(a)) for _ in msg] == code:
			return int(key[:i])
		else:
			i += 1