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

Difficulty: introductory

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))  # round up integer without math.ceil
        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):
    # your code here
    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