Binary with 0 and 1 is good, but binary with only 0 is even better! Originally, this is a concept designed by Chuck Norris to send so called unary messages.

Can you write a program that can send and receive this messages?

Rules

The input message consists of ASCII characters between 32 and 127 (7-bit)
The encoded output message consists of blocks of 0
A block is separated from another block by a space
Two consecutive blocks are used to produce a series of same value bits (only 1 or 0 values):

First block is always 0 or 00. If it is 0, then the series contains 1, if not, it contains 0
The number of 0 in the second block is the number of bits in the series


Example
Let’s take a simple example with a message which consists of only one character (Letter 'C').'C' in binary is represented as 1000011, so with Chuck Norris’ technique this gives:

0 0 - the first series consists of only a single 1
00 0000 - the second series consists of four 0
0 00 - the third consists of two 1

So 'C' is coded as: 0 0 00 0000 0 00
Second example, we want to encode the message "CC" (i.e. the 14 bits 10000111000011) :

0 0 - one single 1
00 0000 - four 0
0 000 - three 1
00 0000 - four 0
0 00 - two 1

So "CC" is coded as: 0 0 00 0000 0 000 00 0000 0 00
Note of thanks
Thanks to the author of the original kata. I really liked this kata. I hope that other warriors will enjoy it too.

Difficulty: introductory

Starter code:

def send(s):
	

Solutions:
from re import compile

REGEX1 = compile(r"0+|1+").findall
REGEX2 = compile(r"(0+) (0+)").findall
binary = "{:07b}".format

def send(s):
    temp = ''.join(binary(ord(c)) for c in s)
    return ' '.join("0 " + '0'*len(x) if x[0] == '1' else "00 " + x for x in REGEX1(temp))

def receive(s):
    temp = ''.join(y if x == '00' else '1'*len(y) for x,y in REGEX2(s))
    return ''.join(chr(int(temp[i:i+7], 2)) for i in range(0, len(temp), 7))

from itertools import groupby

def send(s):
    return toUnary(''.join(f'{ ord(c) :0>7b}' for c in s))

def toUnary(c):
    return ' '.join( f'{"0"*(2-int(b))} {"0"*sum(1 for _ in g)}' for b,g in groupby(c))

def receive(s):
    it   = iter(s.split())
    binS = ''.join( str( len(b)&1 ) * len(n) for b,n in zip(it,it))
    return ''.join( chr( int(binS[i:i+7],2) ) for i in range(0,len(binS),7))

from itertools import groupby


def send(stg):
    bits = "".join(f"{ord(c):07b}" for c in stg)
    return " ".join(f"{'0' * (2 - int(b))} {'0' * len(tuple(l))}" for b, l in groupby(bits))
    

def receive(stg):
    chunks = stg.split()
    bits = zip(chunks[::2], chunks[1::2])
    chars = "".join(f"{2 - len(bit)}" * len(length) for bit, length in bits)
    return "".join(chr(int(chars[i:i+7], 2)) for i in range(0, len(chars), 7))

from itertools import groupby 

def send(s):
    s = ''.join(format(o, '07b') for o in map(ord, s))
    return ' '.join(
        f"{'0' if key == '1' else '00'} {'0' * sum(1 for _ in grp)}"
        for key, grp in groupby(s)
    )

def receive(s):
    it = iter(s.split())
    xs = ''.join(('1' if c == '0' else '0') * len(n) for c, n in zip(it, it))
    return ''.join(chr(int(xs[i:i+7], 2)) for i in range(0, len(xs), 7))

from itertools import groupby

doc = { '1':'0', '0':'00' }

def send(s):
    return ''.join([' '.join( f'{doc[x[0]]} {"0"*x[1]}' for x in code( bit(s) ) )  ])
    
def code(e):
    return [(k,len(list(v))) for k,v in groupby(e)]
    
def bit(e):
    return ''.join( str(bin( ord(x) )[2:]).zfill(7) for x in e )
    
def receive(s):
    return ''.join( chr(int(e, 2)) for e in groups( encode( s.split(' ') ) , 7 ))

def encode(e):
    return ''.join( { v:k for k,v in list(doc.items()) }[e[0]] * len(e[1]) for e in groups(e,2)  )
        
def groups(e, d):
    return [ e[i:i+d] for i in range(0,len(e),d)]
    
    
    


def get_stream(s):
    return "".join(bin(ord(c))[2:].zfill(7) for c in s)

def parse_stream(s):
    return "".join(chr(int(c, 2)) for c in [s[i:i+7] for i in range(0, len(s), 7)])

def get_next(s):
    return s[:max(s.find("0"), s.find("1"))] or s

def get_sequences(s):
    while s:
        n = get_next(s)
        s = s[len(n):]
        if n: yield n

def compose(n):
    return "0" * (2 - int(n[0])) + " " + "0" * len(n)

def decompose(s):
    s = s.split(" ")
    output = ""
    while s:
        output += ({"0":"1","00":"0"})[s.pop(0)] * len(s.pop(0))
    return output

def send(s):
    return " ".join(compose(seq) for seq in get_sequences(get_stream(s)))

def receive(s):
    return parse_stream(decompose(s))


import re

def send(text):
    tmp = (ord(char) for char in text)
    tmp = (f"{x:07b}" for x in tmp)
    tmp = "".join(tmp)
    tmp = re.findall("0+|1+", tmp)
    tmp = (f"{'0' if group[0] == '1' else '00'} {'0' * len(group)}" for group in tmp)
    return " ".join(tmp)

def receive(unary):
    tmp = re.findall("(0+) (0+)", unary)
    tmp = (("0" if digit == "00" else "1") * len(count) for digit, count in tmp)
    tmp = "".join(tmp)
    tmp = re.findall(".{7}", tmp)
    tmp = (chr(int(x, 2)) for x in tmp)
    return "".join(tmp)

import re

def send(s):
    return " ".join(f"{'0' if x[0] == '1' else '00'} {'0' * len(x)}" for x in re.findall("0+|1+", "".join(f"{x:07b}" for x in map(ord, s))))

def receive(s):
    return re.sub(".{7}", lambda x: chr(int(x.group(), 2)), "".join(("1" if x == "0" else "0") * len(y) for x, y in re.findall("(0+) (0+)", s)))

import re
def send(s):
    return' '.join(('0'*(2-int(c[0]))+' '+'0'*len(c))for c in re.findall('1+|0+',''.join(f'{ord(c):07b}'for c in s)))

def receive(s):
    return''.join(chr(int(''.join(a),2))for a in zip(*[iter(''.join(str(2-len(a))*len(b)for a,b in zip(*[iter(s.split())]*2)))]*7))


def send(s):
    r = ''
    state = 0
    for a in (ord(x) for x in s):
        i = 64
        while i > 0:
            b = a & i
            if (state == 0 or state == 2) and b == 0:
                r = r + ' 00 0'
                state = 1
            elif (state == 0 or state == 1) and b != 0:
                r = r + ' 0 0'
                state = 2
            elif (state == 2 and b != 0) or (state == 1 and b == 0):
                r = r + '0'
            i = i >> 1
    return r[1:]


def receive(s):
    r = 0
    i = 0
    state = -1
    u = ''
    for c in s:
        if state == -1:
            if c == '0':
                state = 0
        elif state == 0:
            if c == '0':
                state = 1
            else:
                state = 2
        elif state == 1:
            if c == ' ':
                state = 3
        elif state == 2:
            if c == ' ':
                state = -1
            elif c == '0':
                r = r << 1
                r = r + 1
                i = i + 1
        elif state == 3:
            if c == ' ':
                state = -1
            elif c == '0':
                r = r << 1
                i = i + 1
        if i == 7:
            u = u + chr(r)
            i = 0
            r = 0
    return u