##Task:
You have to write a function `add` which takes two binary numbers as strings and returns their sum as a string.

##Note:
* You are `not allowed to convert binary to decimal & vice versa`.
* The sum should contain `No leading zeroes`.

##Examples:
```
add('111','10'); => '1001'
add('1101','101'); => '10010'
add('1101','10111') => '100100'
```

Difficulty: introductory

Starter code:

def add(a,b):
	

Solutions:
def binary_string_to_int(string):
    return sum((d == '1') * 2**i for i, d in enumerate(string[::-1]))

def add(a, b):
    return '{:b}'.format(binary_string_to_int(a) + binary_string_to_int(b))

from itertools import zip_longest

ADDER = {
    ('0', '0', '0'): ('0', '0'),
    ('0', '0', '1'): ('1', '0'),
    ('0', '1', '0'): ('1', '0'),
    ('0', '1', '1'): ('0', '1'),
    ('1', '0', '0'): ('1', '0'),
    ('1', '0', '1'): ('0', '1'),
    ('1', '1', '0'): ('0', '1'),
    ('1', '1', '1'): ('1', '1'),
}


def add(x, y):
    x = x.lstrip('0')
    y = y.lstrip('0')

    if not x:
        return y or '0'
    elif not y:
        return x

    sum_digits, carry = [], '0'
    for x_digit, y_digit in zip_longest(x[::-1], y[::-1], fillvalue='0'):
        sum_digit, carry = ADDER[(x_digit, y_digit, carry)]
        sum_digits.append(sum_digit)

    if carry == '1':
        sum_digits.append(carry)

    return ''.join(sum_digits)[::-1]



def add(a,b):
  out, ap, bp, r = '', list(a.lstrip('0')), list(b.lstrip('0')), 0
  while (len(ap) > 0 or len(bp) > 0 or r > 0):
    ac, bc = ap.pop() if len(ap) > 0 else None, bp.pop() if len(bp) else None
    total = r + (ac == '1') + (bc == '1')
    out = ('1' if total % 2 else '0') + out
    r = 0 if total < 2 else 1
  return out or '0'

def b2i(b):
    return sum(1 << i for i, x in enumerate(b[::-1]) if x == '1')

def add(a, b):
    return format(b2i(a) + b2i(b), 'b')

def bitAdd(b, co):
    if b == '00':
        if co: 
            return '1', False
        else:
            return '0', False
        
    if b in ['01', '10']: 
        if co: 
            return '0', True
        else:
            return '1', False
        
    if b == '11':
        if co: 
            return '1', True
        else:
            return '0', True
        

def add(a, b):
    if len(a) < len(b):
        a = ((len(b)-len(a))*'0')+a
    else:
        b = ((len(a)-len(b))*'0')+b
    #
    bits=[i+j for i, j in zip(reversed(a),reversed(b))]
    co = False
    ans = ['' for i in range(len(a))]
    for i,b in enumerate(bits):
        ans[i], co = bitAdd(b, co)
    #
    if co: ans.append('1')
    ans = ''.join(reversed(ans)).lstrip('0')
    #
    if ans == '': return '0'
    return ans

from itertools import zip_longest
def add(a, b):
    d = ('00', '01', '10', '11')

    arr, k = [], '0'
    for m, n in zip_longest(a[::-1], b[::-1], fillvalue = '0'):
        k, r = d[(m, n, k).count('1')]
        arr.append(r)
    arr.append(k)
    return ''.join(arr[::-1]).lstrip('0') or '0'



def add(a,b):
    out = ""
    carry = 0
    
    a = a.lstrip("0")
    b = b.lstrip("0")
    
    max_l = max(len(a), len(b))
    a = a.rjust(max_l, "0")
    b = b.rjust(max_l, "0")

    for i in range(1, max_l + 1):
        s, carry = carry, 0
        s += 1 if a[-i] == "1" else 0
        s += 1 if b[-i] == "1" else 0
        
        carry = s > 1
        out += "01"[s%2]
        
    out += "1"*carry
    return out[::-1] if len(out) > 0 else "0"

def add(a, b):
    longer = max(len(a), len(b))
    a, b = [x.zfill(longer) for x in [a, b]]
    p = {'000': '00', '001': '10',
         '010': '10', '011': '01',
         '100': '10', '101': '01',
         '110': '01', '111': '11'}
    result = []
    c = '0'
    for x, y in zip(reversed(a), reversed(b)):
        r, c = p[x + y + c]
        result.append(r)
    if c == '1': result.append(c)
    return ''.join(reversed(result)).lstrip('0') or '0'