Remember the game 2048?

The main part of this game is merging identical tiles in a row. 

* Implement a function that models the process of merging all of the tile values in a single row.  
* This function takes the array line as a parameter and returns a new array with the tile values from line slid towards the front of the array (index 0) and merged.
* A given tile can only merge once.
* Empty grid squares are represented as zeros.
* Your function should work on arrays containing arbitrary number of elements.


## Examples

```
merge([2,0,2,2])  -->  [4,2,0,0]
```

Another example with repeated merges: 

```
merge([4,4,8,16])  -->  [8,8,16,0]
merge([8,8,16,0])  -->  [16,16,0,0]
merge([16,16,0,0]) -->  [32,0,0,0]
```

Source: codewars | Difficulty: EASY
Tags: Data structures

Game theory

Starter code: def merge(line):
	

Solutions:
from itertools import groupby

def merge(line):
	merged = []
	for (k, g) in groupby((v for v in line if v)):
		g = list(g)
		(n, r) = divmod(len(g), 2)
		if n:
			merged.extend([k * 2] * n)
		if r:
			merged.append(k)
	return merged + [0] * (len(line) - len(merged))


def merge(line):
	line = ungap(line)
	for i in range(len(line) - 1):
		if line[i] == line[i + 1]:
			(line[i], line[i + 1], i) = (line[i] * 2, 0, i + 1)
	return ungap(line)

def ungap(line):
	return [n for n in line if n] + [0] * line.count(0)


from itertools import chain, groupby

def merge_group(grp):
	xs = list(grp)
	(q, r) = divmod(len(xs), 2)
	return [xs[0] * 2] * q + [xs[0]] * r

def merge(line):
	n = len(line)
	line = list(filter(None, line))
	line = list(chain.from_iterable((merge_group(grp) for (_, grp) in groupby(line))))
	return line + [0] * (n - len(line))


def merge(row):
	(new_row, last_tile) = ([], 0)
	for tile in row:
		if tile and tile == last_tile:
			new_row[-1] *= 2
			last_tile = 0
		elif tile != 0:
			new_row.append(tile)
			last_tile = tile
	return new_row + [0] * (len(row) - len(new_row))


def merge(line):
	viper = [x for x in line if x]
	if len(viper) > 1:
		(head, neck) = viper[:2]
		equal = head == neck
		head += neck * equal
		tail = merge(viper[1 + equal:])
		return [head] + tail + [0] * (len(line) - len(tail) - 1)
	else:
		return line


def merge(line):
	if line[0] != 0 and line[0] == line[1]:
		if line[2] != 0 and line[2] == line[3]:
			return [line[0] + line[1], line[2] + line[3], 0, 0]
		else:
			return [line[0] + line[1], line[2], line[3], 0]
	elif line[0] != 0 and line[1] == 0 and (line[0] == line[2]):
		return [line[0] + line[2], line[3], 0, 0]
	elif line[0] != 0 and line[1] == 0 and (line[2] == 0) and (line[0] == line[3]):
		return [line[0] + line[3], 0, 0, 0]
	elif line[0] != 0:
		if line[1] != 0 and line[1] == line[2]:
			return [line[0], line[1] + line[2], line[3], 0]
		elif line[1] != 0 and line[2] == 0 and (line[1] == line[3]):
			return [line[0], line[1] + line[3], 0, 0]
		elif line[1] != 0:
			if line[2] != 0 and line[2] == line[3]:
				return [line[0], line[1], line[2] + line[3], 0]
			else:
				return [line[0], line[1], line[2], line[3]]
		elif line[2] != 0 and line[2] == line[3]:
			return [line[0], line[2] + line[3], 0, 0]
		else:
			return [line[0], line[2], line[3], 0]
	elif line[1] != 0 and line[1] == line[2]:
		return [line[1] + line[2], line[3], 0, 0]
	elif line[1] != 0 and line[2] == 0 and (line[1] == line[3]):
		return [line[1] + line[3], 0, 0, 0]
	elif line[1] != 0:
		if line[2] != 0 and line[2] == line[3]:
			return [line[1], line[2] + line[3], 0, 0]
		else:
			return [line[1], line[2], line[3], 0]
	elif line[2] != 0 and line[2] == line[3]:
		return [line[2] + line[3], 0, 0, 0]
	else:
		return [line[2], line[3], 0, 0]

def merge(line):
	(i, res) = (0, [])
	while i < len(line):
		x = line[i]
		if x:
			for (j, y) in enumerate(line[i + 1:], 1):
				if y:
					if x == y:
						res.append(x + y)
						i += j
					else:
						res.append(x)
					break
			else:
				res.append(x)
		i += 1
	return res + [0] * (len(line) - len(res))


def merge(line):
	(mrg, lst, l, fr) = ([], [x for x in line if x], len(line), 0)
	for e in lst:
		if not fr:
			fr = e
		elif fr == e:
			mrg.append(fr + e)
			fr = 0
		else:
			mrg.append(fr)
			fr = e
	mrg.append(fr)
	while len(mrg) < l:
		mrg.append(0)
	return mrg


def merge(line):
	(a, li, i) = (list(filter(lambda x: bool(x), line)), [], 0)
	while i < len(a):
		if i < len(a) - 1 and a[i] == a[i + 1]:
			a[i] += a[i + 1]
			li.append(a[i])
			i += 1
		else:
			li.append(a[i])
		i += 1
	return li + [0] * (len(line) - len(li))


def merge(line):
	temp = [x for x in line if x != 0]
	res = []
	while temp:
		if len(temp) > 1 and temp[0] == temp[1]:
			res.append(temp.pop(0) + temp.pop(0))
		else:
			res.append(temp.pop(0))
	return res + [0] * (len(line) - len(res))


def merge(a):
	a = [i for i in a if i] + [i for i in a if not i]
	for i in range(len(a) - 1):
		if a[i] == a[i + 1]:
			(a[i], a[i + 1]) = (2 * a[i], 0)
	return [i for i in a if i] + [i for i in a if not i]