In this kata, your task is to implement what I call **Iterative Rotation Cipher (IRC)**. To complete the task, you will create an object with two methods, `encode` and `decode`. (For non-JavaScript versions, you only need to write the two functions without the enclosing dict)

Input
The encode method will receive two arguments — a positive integer n and a string value.
The decode method will receive one argument — a string value.
Output
Each method will return a string value.
How It Works
Encoding and decoding are done by performing a series of character and substring rotations on a string input.
Encoding: The number of rotations is determined by the value of n. The sequence of rotations is applied in the following order:
 Step 1: remove all spaces in the string (but remember their positions)
 Step 2: shift the order of characters in the new string to the right by n characters
 Step 3: put the spaces back in their original positions
 Step 4: shift the characters of each substring (separated by one or more consecutive spaces) to the right by n

Repeat this process until it has been completed n times in total.
The value n is then prepended to the resulting string with a space.
Decoding: Decoding simply reverses the encoding process.
Test Example

```python
quote = 'If you wish to make an apple pie from scratch, you must first invent the universe.'
solution = '10 hu fmo a,ys vi utie mr snehn rni tvte .ysushou teI fwea pmapi apfrok rei tnocsclet'
IterativeRotationCipher['encode'](10,quote) == solution; //True

'''Step-by-step breakdown:
Step 1 — remove all spaces:
'Ifyouwishtomakeanapplepiefromscratch,youmustfirstinventtheuniverse.'

Step 2 — shift the order of string characters to the right by 10:
'euniverse.Ifyouwishtomakeanapplepiefromscratch,youmustfirstinventth'

Step 3 — place the spaces back in their original positions:
'eu niv erse .I fyou wi shtom ake anap plepiefr oms crat ch,yo umustf irs tinventth'

Step 4 — shift the order of characters for each space-separated substring to the right by 10:
'eu vni seer .I oufy wi shtom eak apan frplepie som atcr ch,yo ustfum sir htinventt'

Repeat the steps 9 more times before returning the string with '10 ' prepended.
'''
```

Technical Details

- Input will always be valid.
- The characters used in the strings include any combination of alphanumeric characters, the space character, the newline character, and any of the following: `_!@#$%^&()[]{}+-*/="'<>,.?:;`.

If you enjoyed this kata, be sure to check out [my other katas](https://www.codewars.com/users/docgunthrop/authored).

Difficulty: introductory

Starter code:

def encode(n,strng):
	

Solutions:
def shift(string, step):
    i = (step % len(string)) if string else 0
    return f"{string[-i:]}{string[:-i]}"

def encode(n, string):
    for _ in range(n):
        shifted = shift(string.replace(" ", ""), n)
        l = [len(word) for word in string.split(" ")]
        string = " ".join(shift(shifted[sum(l[:i]):sum(l[:i+1])], n) for i in range(len(l)))
    return f"{n} {string}"

def decode(string):
    n, string = int(string.partition(" ")[0]), string.partition(" ")[2]
    for _ in range(n):
        shifted = shift("".join(shift(word, -n) for word in string.split(" ")), -n)
        l = [len(word) for word in string.split(" ")]
        string = " ".join(shifted[sum(l[:i]):sum(l[:i+1])] for i in range(len(l)))
    return string


def rotate(n, s):
    if not s: return s
    n = -n % len(s)
    return s[n:] + s[:n]

def cipher(n, s):
    sp = [i for i, c in enumerate(s) if c == ' '] + [len(s)]
    s = s.split(' ')
    if n < 0: s = [rotate(n, w) for w in s]
    s = rotate(n, ''.join(s))
    s = [s[i+1-x: j-x] for x, (i, j) in enumerate(zip([-1] + sp, sp))]
    if n > 0: s = [rotate(n, w) for w in s]
    return ' '.join(s)

def encode(n, s):
    for _ in range(n): s = cipher(n, s)
    return f'{n} {s}'

def decode(s):
    n, s = s.split(' ', 1)
    n = int(n)
    for _ in range(n): s = cipher(-n, s)
    return s

def encode(n,strng):
    for _ in range(n):
        wos, spa, new, a = '', [], '', []

        for i in range(len(strng)):
            if strng[i] == ' ': spa.append(i)
            else: wos += strng[i]
        shifted = []
        for i in range(len(wos)): shifted.insert((i+n)%len(wos), wos[i])
        for i in spa: shifted.insert(i, ' ')
        for i in [i for i in ''.join(shifted).split(' ')]:
            tem = []
            for j in range(len(i)): tem.insert((j+n)%len(i), i[j])
            a.append(''.join(tem))
        strng = ' '.join(a)
        
    return '{} {}'.format(n, strng)

def decode(strng):
    n = int(strng.split(' ')[0])
    strng = strng[len(str(n))+1:]
    for _ in range(n):
        a, spa = [], []
        for i in range(len(strng)):
            if strng[i] == ' ':spa.append(i)
        for i in [i for i in strng.split(' ')]:
            tem = []
            for j in range(len(i)): tem.insert((j-n)%len(i), i[j])
            a.append(''.join(tem))
        wos, shifted = ''.join(a), []
        
        for i in range(len(wos)): shifted.insert((i-n)%len(wos), wos[i])
        
        for i in spa:
            shifted.insert(i, ' ')
        strng = ''.join(shifted)
    return(strng)

def encode(n, cleartext):
    def rotate_right(sequence, n):
        n %= len(sequence) or 1
        return sequence[-n:] + sequence[:-n]
    for _ in range(n):
        letters = iter(rotate_right([c for c in cleartext if c != ' '], n))
        cleartext = ''.join(c if c == ' ' else next(letters) for c in cleartext)
        cleartext = ' '.join(rotate_right(word, n) for word in cleartext.split(' '))
    return f'{n} {cleartext}'

def decode(ciphertext):
    def rotate_left(sequence, n):
        n %= len(sequence) or 1
        return sequence[n:] + sequence[:n]
    n, ciphertext = ciphertext.split(' ', 1)
    n = int(n)
    for _ in range(n):
        ciphertext = ' '.join(rotate_left(word, n) for word in ciphertext.split(' '))
        letters = iter(rotate_left([c for c in ciphertext if c != ' '], n))
        ciphertext = ''.join(c if c == ' ' else next(letters) for c in ciphertext)
    return ciphertext

SPACE, NULL_STR = " ", ""

def rotate(n, s):
    if not s: return NULL_STR
    
    if SPACE in s:
        return SPACE.join(rotate(n, word) for word in s.split(SPACE))
    
    else:
        n %= len(s)
        return s[-n:] + s[:-n]


def cipher(n, s):
    # extract spaces
    spaces = [idx for idx, char in enumerate(s) if char == SPACE]
    
    for _ in range(abs(n)):
        # rotate words (decoding)
        if n < 0: s = rotate(n, s)
        
        # remove spaces, rotate string, put back spaces
        s = s.replace(SPACE, NULL_STR)
        s = rotate(n, s)
        for idx in spaces: s = s[:idx] + SPACE + s[idx:]
        
        # rotate words (encoding)
        if n > 0: s = rotate(n, s)
    
    return s


def encode(n, s):
    return str(n) + SPACE + cipher(n, s)


def decode(s):
    n, s = s.split(SPACE, 1)
    n = int(n)
    return cipher(-n, s)

def encode(n,strng):
    new_strng = strng.split(" ")
    for i in range(n):
        strng = "".join(strng.split(" "))
        strng = strng[-n:] + strng[:-n]
        index_0 = 0
        for i in range(len(new_strng)):
            index = len(new_strng[i]) + index_0
            new_strng[i] = strng[index_0:index]
            index_0 = index
        strng = ""
        for i in new_strng:
            change = n % len(i) if len(i) != 0 else i.count(" ")
            strng += i[-change:] + i[:-change] + " "
        strng = strng[:-1]
    return f"{n} " + strng

def decode(strng):
    i = 0
    num = ""
    while strng[i].isdigit():
        num += strng[i]
        i += 1
    num = int("".join(num))
    strng = strng[len(str(num))+1:]
    new_strng = strng.split(" ")
    strng = "".join(strng.split(" "))
    for i in range(num):
        index_0 = 0
        for i in range(len(new_strng)):
            index = len(new_strng[i]) + index_0
            new_strng[i] = strng[index_0:index]
            index_0 = index
        strng = ""
        for i in new_strng:
            change = num % len(i) if len(i) != 0 else i.count(" ")
            strng += i[change:] + i[:change]
        strng = strng[num:] + strng[:num]
    index_0 = 0
    for i in range(len(new_strng)):
        index = len(new_strng[i]) + index_0
        new_strng[i] = strng[index_0:index]
        index_0 = index
    return " ".join(new_strng)

from collections import deque
from itertools import chain, count

def _code(n, s, sign):
    non_space, offset = [], count()
    slice_points = [0,] + [
            i - (0 if c != ' ' else next(offset))
            for i, c in enumerate(s) 
            if c == ' ' or non_space.append(c)
        ] + [len(s),]
    slices = [slice(start, end) for start, end in zip(slice_points, slice_points[1:])]
    ops = ([slice(None),] * (sign == 1) + slices + [slice(None),] * (sign == -1)) * n
    for op in ops:
        d = deque(non_space[op])
        d.rotate(sign * n)
        non_space[op] = d
    return ' '.join(''.join(non_space[x]) for x in slices)

def encode(n, s):
    ciphered = _code(n, s, 1)
    return f'{n} {ciphered}'

def decode(s):
    n, s = s.split(' ', 1)
    return _code(int(n), s, -1)

import re
from collections import deque
def encode(n,s):
    s = s.replace('\n', '`')
    for i in range(n):
        pos, s = get_pos(s), deque(s.replace(' ', ''))
        deque.rotate(s, n)
        s = rotate(set_pos(s,pos),n,1)
    return str(n) + ' ' + s.replace('`','\n')

def decode(s):
    n, s = re.search(r'^\d+', s).group(), s.replace('\n','`')
    s, n = s[len(n) + 1:], int(n)
    for i in range(n):
        pos, s = get_pos(s), deque(''.join(deque(rotate(s,n,-1))).replace(' ', ''))
        deque.rotate(s, -n)
        s = ''.join(set_pos(s,pos))
    return s.replace('`','\n')

get_pos = lambda s: [l for l, j in enumerate(s) if j == ' ']
def rotate(s,n,c):
    li = []
    for k in re.findall(r'(.+?)(\s+)|(.+$)', ''.join(s)):
          t = deque(k[0] or k[-1]) ; deque.rotate(t, n*c)
          li.append(''.join(t) + k[1])
    return ''.join(li)
def set_pos(s,position):
    for pos in position : s.insert(pos, ' ')
    return s

def encode(n,s):
    for i in range(n):
        s =''.join(space(re(''.join([decore(e, n)for e in space(re(decore(s.replace(' ',''),n)),ws(s)).split(' ')])),ws(s)))  
    return str(n)+' '+s
    
def decode(s):
    n, s = s.split(' ', 1)
    n, sps = int(n), ws(s) 
    for i in range(n): 
        s = ''.join(space(re(decore(''.join([decore(e,-n)for e in s.split(' ')]),-n)),sps))
    return s

def space(stg, arr):
    for i in arr: stg.insert(i, ' ') 
    return ''.join(stg)

def decore(code, key):    
    l = (len(code) or 1)
    i = key % l
    return  code[-i:] + code[:-i]
    
ws = lambda s: [ i for i,e in enumerate(s) if e ==' ']
re = lambda l: [e for e in l]

def rotate(n, s):
    i = -n % len(s) if len(s) > 0 else 1
    return s[i:] + s[:i]

def cipher(n, s):
    sp = [i for i, c in enumerate(s) if c == " "] + [len(s)]
    s = s.split(' ')
    if n < 0: 
        s = [rotate(n, w) for w in s]
    s = rotate(n, ''.join(s))
    s = [s[i+1-x:j-x] for x, (i, j) in enumerate(zip([-1] + sp, sp))]
    if n > 0: 
        s = [rotate(n, w) for w in s]
    return ' '.join(s)
    
def encode(n, strng):
    s = strng
    for _ in range(n):
        s = cipher(n, s)
    return "{} {}".format(n, s)
    
def decode(strng):
    n, s = strng.split(" ", 1)
    n = int(n)
    for _ in range(n):
        s = cipher(-n, s)
    return s