Create a function `sierpinski` to generate an ASCII representation of a Sierpinski triangle of order **N**. 

Seperate each line with `\n`. You don't have to check the input value.

The output should look like this: 

     sierpinski(4)
                   *               
                  * *              
                 *   *             
                * * * *            
               *       *           
              * *     * *          
             *   *   *   *         
            * * * * * * * *        
           *               *       
          * *             * *      
         *   *           *   *     
        * * * *         * * * *    
       *       *       *       *   
      * *     * *     * *     * *  
     *   *   *   *   *   *   *   * 
    * * * * * * * * * * * * * * * *

Difficulty: EASY
Tags: String algorithms

Starter code:
def sierpinski(n):
	

Solutions:
def sierpinski(n):
	t = ['*']
	for _ in range(n):
		t = [r.center(2 * len(t[-1]) + 1) for r in t] + [r + ' ' + r for r in t]
	return '\n'.join(t)


def sierpinski(n):
	lines = ['*']
	for i in range(2, n + 2):
		lines = [l.center(2 ** i - 1) for l in lines] + [f'{l} {l}' for l in lines]
	return '\n'.join(lines)


sierpinski = lambda n, pr=['*'], sp=3: sierpinski(n - 1, pr + [j + ' ' * len(pr[-1 - i]) + j for (i, j) in enumerate(pr)], sp * 2 + 1) if n else '\n'.join([i.center(sp // 2) for i in pr])


def s(n):
	xs = [1]
	yield xs
	for i in range(n):
		while True:
			xs = [a ^ b for (a, b) in zip([0] + xs, xs + [0])]
			yield xs
			if all(xs):
				break

def sierpinski(n):
	xss = list(s(n))
	width = len(xss) * 2 - 1
	return '\n'.join((' '.join((' *'[x] for x in xs)).center(width) for xs in xss))


def sierpinski(n):
	return '\n'.join((l.center(2 ** (n + 1) - 1) for l in addrows(n, ['*'])))

def addrows(n, t):
	for _ in range(n):
		t += [l.ljust(len(t[-1])) + ' ' + l for l in t]
	return t


def sierpinski(n):
	if n == 0:
		return '*'
	s = sierpinski(n - 1).split('\n')
	ss = []
	for i in range(2 ** n // 2):
		ss.append(s[i].center(2 ** n * 2 - 1))
	for i in range(2 ** n // 2):
		ss.append(s[i] + ' ' + s[i])
	return '\n'.join(ss)


def sierpinski(n):
	if n == 1:
		return ' * \n* *'
	s = sierpinski(n - 1).split('\n')
	n = len(s[0])
	r = []
	for row in s:
		r.append(' ' * ((n + 1) // 2) + row + ' ' * ((n + 1) // 2))
	for row in s:
		r.append(row + ' ' + row)
	return '\n'.join(r)


def sierpinski(n):
	if n == 0:
		return '*'
	lower = sierpinski(n - 1).splitlines()
	result = [s.center(2 * len(s) + 1) for s in lower]
	result += [s + ' ' + s for s in lower]
	return '\n'.join(result)


def sierpinski(n):
	if n == 0:
		return '*'
	lines = sierpinski(n - 1).split('\n')
	upper = [' ' * 2 ** (n - 1) + l + ' ' * 2 ** (n - 1) for l in lines]
	lower = [l + ' ' + l for l in lines]
	return '\n'.join(upper + lower)


SIERPINSKI = {1: [' * ', '* *']}

def join_lesser(fig):
	width = len(fig[-1]) + 1
	result = []
	for line in fig:
		padding = ' ' * (width // 2)
		result.append(padding + line + padding)
	for line in fig:
		result.append(line + ' ' * (width - len(line)) + line)
	return result

def get_sierpinski(n):
	if n in SIERPINSKI:
		return SIERPINSKI[n]
	lesser = get_sierpinski(n - 1)
	SIERPINSKI[n] = join_lesser(lesser)
	return SIERPINSKI[n]

def sierpinski(n):
	return '\n'.join(get_sierpinski(n))