## Task

Given a string, add the fewest number of characters possible from the front or back to make it a palindrome.

## Example

For the input `cdcab`, the output should be `bacdcab`

## Input/Output

Input is a string consisting of lowercase latin letters with length 3 <= str.length <= 10

The output is a palindrome string satisfying the task.

For s = `ab` either solution (`aba` or `bab`) will be accepted.

Difficulty: introductory

Starter code:

def build_palindrome(s):
	

Solutions:
def build_palindrome(s):
    for n in range(len(s), -1, -1):
        if s[:n] == s[:n][::-1]:
            return s[n:][::-1] + s
        if s[-n:] == s[-n:][::-1]:
            return s + s[:-n][::-1]

def build_palindrome(s):
    a = s[1:][::-1] + s
    temp = s
    for i in range(len(s)+1):
        temp = s[::-1][:i] + s
        if temp == temp[::-1] and len(temp)<len(a):
            a = temp

    b = s + s[::-1]
    temp = s
    for i in range(len(s)+1):
        temp = s + s[::-1][i:]
        if temp == temp[::-1] and len(temp)<len(b):
            b = temp
    if len(a)>len(b):
        return b
    else:
        return a


def is_palindrome(s):
    """Check if s is a palindrome"""
    return s == s[::-1]


def left_strip_palindrome(s):
    """Keeps stripping from left to find a palindrome. If not found return None. 
    If found return the stripped characters in stripping order"""
    for i in range(len(s)-1):
        if is_palindrome(s[i:]):
            return s[:i]
    return None

def right_strip_palindrome(s):
    """Keeps stripping from right to find a palindrome. If not found return None. 
    If found return the stripped characters in stripping order"""
    for i in range(-1,1-len(s),-1):
        if is_palindrome(s[:i]):
            return s[i:]
            
def build_palindrome(s):
    """Build a palindrome by adding the min number of characters possible."""
    lsp = left_strip_palindrome(s)
    rsp = right_strip_palindrome(s)
    # Answer is obtained by getting the stripped characters and add them in reverse order 
    # to the opps direction they were stripped from in reverse direction.
    if lsp is not None:
        lsp_ans = s+lsp[::-1]
        if rsp is not None:
            rsp_ans = rsp[::-1]+s
            # In the case both left stripping and right stripping works, return the shortest answer.
            return min((lsp_ans,rsp_ans), key=len)
        return lsp_ans
            
    if rsp is not None:
        rsp_ans = rsp[::-1]+s
        return rsp_ans
    
    # If stripping does not work return the string with the copy of all characters 
    # but the first concatenated at the starting in reverse order.
    return s[1:][::-1]+s


def is_palindrome(s):
    return s == s[::-1]

def build_palindrome(s):
    for i in range(len(s)):
        x = s + s[:i][::-1]
        if is_palindrome(x):
            return x
        x = s[-i or len(s):][::-1] + s
        if is_palindrome(x):
            return x

def build_palindrome(s,i=0):
    def bp(s):
        a = s+s[:i][::-1]
        if a == a[::-1]: return a
    return bp(s) or bp(s[::-1]) or build_palindrome(s,i+1)


def build_palindrome(s):
    if list(s) == list(s)[::-1]:
        return s
    
    for i in range(1, len(s)):
        if s[i:] == s[i:][::-1]: #checks if element i -> end of list == element i -> end of list, in reverse ([][] calls on elements of a nexted list)
            break
    endAdd = s + s[0:i][::-1] #adds the non symetric part to the begining of the string, in reverse order
    
    for i in range(1, len(s)):
        if s[:-i] == s[:-i][::-1]: #checks if element 0 -> i == element 0 -> i, in reverse ([][] calls on elements of a nexted list)
            break    
    frontAdd = s[-i:][::-1] + s #adds the non symetric part to the begining of the string, in reverse order
    
    print(endAdd)
    print(frontAdd)
    if len(list(endAdd)) <= len(list(frontAdd)):
        #print('1') #too see which one gets printed
        return endAdd
    else:
        #print('2') #too see which one gets printed
        return frontAdd

def is_palindrome(word: str) -> bool:
    """Tell if the given word is a palindrome."""
    return word[::-1] == word


def build_left_palindrome(word: str) -> str:
    """Build the shorter palindrome adding letters to the left.

    We search the maximal prefix that is a palindrome. Adding the
    corresponding suffix to the left gives the shorter solution.
    """
    length = len(word)
    while not is_palindrome(word[:length]):
        length -= 1
    return word[length:][::-1] + word


def build_right_palindrome(word: str) -> str:
    """Build the shorter palindrome adding letters to the right."""
    return build_left_palindrome(word[::-1])[::-1]


def build_palindrome(word: str) -> str:
    """Add letters to the right or the left of the given word to get the
    shorter palindrome.
    """
    return sorted([
        build_left_palindrome(word), 
        build_right_palindrome(word)
    ], key=len)[0]

def build_palindrome(s):
    l = len(s)
    left = next(l-i for i in range(l, 0, -1) if s[:i] == s[i-1::-1])
    right = next(l-i for i in range(l, 0, -1) if s[-i:] == s[:-i-1:-1] or left == l-i)
    return s[:-left-1:-1] + s if left <= right else s + s[right-1::-1]

def build_palindrome(s):
    a = s[1:][::-1] + s
    b = s + s[::-1]
    temp = s
    for i in range(len(s)+1):
        temp = s[::-1][:i] + s
        if temp == temp[::-1] and len(temp)<len(a):
            a = temp
        temp = s + s[::-1][i:]
        if temp == temp[::-1] and len(temp)<len(b):
            b = temp


    if len(a)>len(b):
        return b
    else:
        return a


def build_palindrome(s):
  rev=s[::-1]
  for i in range(len(s)):    
      if s[i:]==s[i:][::-1]: return s+s[:i][::-1]
      if rev[i:]==rev[i:][::-1]: return rev[:i]+s