# Task
 Miss X has only two combs in her possession, both of which are old and miss a tooth or two. She also has many purses of different length, in which she carries the combs. The only way they fit is horizontally and without overlapping. Given teeth' positions on both combs, find the minimum length of the purse she needs to take them with her.

 It is guaranteed that there is at least one tooth at each end of the comb. 

 - Note, that the combs can not be rotated/reversed.

# Example

 For `comb1 = "*..*" and comb2 = "*.*"`, the output should be `5`

 Although it is possible to place the combs like on the first picture, the best way to do this is either picture 2 or picture 3.

 ![](https://codefightsuserpics.s3.amazonaws.com/tasks/combs/img/cbs.png?_tm=1484930552851)

# Input/Output


 - `[input]` string `comb1`

   A comb is represented as a string. If there is an asterisk ('*') in the ith position, there is a tooth there. Otherwise there is a dot ('.'), which means there is a missing tooth on the comb.

   Constraints: 1 ≤ comb1.length ≤ 10.
   
   

 - `[input]` string `comb2`

   The second comb is represented in the same way as the first one.

   Constraints: 1 ≤ comb2.length ≤ 10.
   

 - `[output]` an integer

   The minimum length of a purse Miss X needs.

Difficulty: introductory

Starter code:

def combs(comb1, comb2):
	

Solutions:
def combs(a, b):
    return min(mesh(a, b), mesh(b, a))

def mesh(a, b):
    for i in range(len(a)):
        for j, k in zip(a[i:], b):
            if j + k == '**': break
        else:
            return max(i + len(b), len(a))
    return len(a) + len(b)            

def combs(comb1, comb2):
    options = []
    for i in range(max(len(comb1), len(comb2))+1):
        if ('*','*') not in zip(' '*i+comb1, comb2):
            options.append( max( len(comb1)+i, len(comb2) ) )
        if ('*','*') not in zip(comb1, ' '*i+comb2):
            options.append( max( len(comb1), len(comb2)+i ) )
    return min(options)

def to_bin(comb):
    s = ''.join(('1' if d == '*' else '0' for d in comb))
    return (int(s, 2))

def shifter(comb1, comb2):
    b1, b2 = to_bin(comb1), to_bin(comb2)
    sh = 0
    while b1 & (b2 << sh):
        sh += 1
    return max(len(comb1), len(comb2) + sh)

def combs(comb1, comb2):
    return min(shifter(comb1, comb2), shifter(comb2, comb1))

def combs(comb1, comb2):
    c1 = int(comb1.replace('*', '1').replace('.', '0'), 2)
    c2 = int(comb2.replace('*', '1').replace('.', '0'), 2)
    def r(x, y):
        if x.__xor__(y) == x + y:
            return max(x.bit_length(), y.bit_length())
        return r(x<<1,y)
    return min(r(c1,c2), r(c2,c1))

def combs(comb1, comb2):
    return min((next(max(i + len(c2), len(c1)) for i in range(len(c1 + c2)) if not ("*", "*") in list(zip((c1 + "." * len(c2))[i:], c2))) for c1, c2 in ((comb1, comb2), (comb2, comb1))))


# very ugly one-liner, I wouldn't do this for real. But I find the clean way is overkill.


def combo(*letters):
    if set(letters) == {'*'} : return 'X'
    if set(letters) == {'.'} : return '.'
    return '*'
    

def combs(*combs):
    print(combs)
    combos = []
    combs = sorted(combs, key=len)
    combs = [combs[0]+'.'*len(combs[1]), '.'*len(combs[0])+combs[1]]
    for _ in range(len(combs[1])):
        combos.append(''.join(combo(a,b) for a,b in zip(*combs)).strip('.'))
        combs[0] = '.' + combs[0]
        combs[1] = combs[1] + '.'
            
    return min(len(c) for c in combos if 'X' not in c)
    
    
    
        
        
        


c,combs=lambda s:int(s.translate({42:49,46:48}),2),lambda a,b:(lambda u,v:min(len(bin(x|y))-2for x,y in((u<<-min(0,n),v<<max(0,n))for n in range(-len(b),len(a)+1))if x&y<1))(c(a),c(b))

def passage(comb1, comb2):
    for i in range(len(comb1)):
        cover = 0
        for j, s in enumerate(comb1[i:]):
            if j == len(comb2):
                return len(comb1)
            if s == comb2[j] == "*":
                break
            cover += 1
        else:
            return len(comb1) + len(comb2) - cover
    return len(comb1 + comb2)


def combs(comb1, comb2):
    comb2, comb1 = sorted([comb1, comb2], key=lambda x: len(x))
    return min(passage(comb1, comb2), passage(comb1[::-1], comb2[::-1]))
    

            


def combs(c1, c2):
    n = len(c1)
    m = len(c2)
    c2 = n*'.'+c2+n*'.'
    
    min_len = 100
    for sh in range(n+m+1):
        l = n + (sh-n)*(sh>n) + (m-sh)*(m>sh)
        fit = True
        for k in range(n):
            if (c2[sh+k]+c1[k]).count('*') == 2:
                fit = False
        if fit:
            min_len = min(min_len,l)
            
    return min_len


def combs(comb1, comb2):
    n1, n2 = len(comb1), len(comb2)
    c1 = int(comb1.replace('*', '1').replace('.', '0'), 2)
    c2 = int(comb2.replace('*', '1').replace('.', '0'), 2)
    return min(next(max(n1, i + n2) for i in range(1, 11) if c1 & (c2 << i) == 0),
               next(max(n2, i + n1) for i in range(1, 11) if c2 & (c1 << i) == 0))