_A mad sociopath scientist just came out with a brilliant invention! He extracted his own memories to forget all the people he hates! Now there's a lot of information in there, so he needs your talent as a developer to automatize that task for him._

> You are given the memories as a string containing people's surname and name (comma separated). The scientist marked one occurrence of each of the people he hates by putting a '!' right before their name.

**Your task is to destroy all the occurrences of the marked people.
One more thing ! Hate is contagious, so you also need to erase any memory of the person that comes after any marked name!**

---
Examples
---
---
Input:
```
"Albert Einstein, !Sarah Connor, Marilyn Monroe, Abraham Lincoln, Sarah Connor, Sean Connery, Marilyn Monroe, Bjarne Stroustrup, Manson Marilyn, Monroe Mary"
```
Output:
```
"Albert Einstein, Abraham Lincoln, Sean Connery, Bjarne Stroustrup, Manson Marilyn, Monroe Mary"
```
=> We must remove every memories of Sarah Connor because she's marked, but as a side-effect we must also remove all the memories about Marilyn Monroe that comes right after her! Note that we can't destroy the memories of Manson Marilyn or Monroe Mary, so be careful!

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Starter code: def select(memory):
	

Solutions:
def select(memory):
	lst = memory.split(', ')
	bad = {who.strip('!') for (prev, who) in zip([''] + lst, lst + ['']) if who.startswith('!') or prev.startswith('!')}
	return ', '.join((who for who in map(lambda s: s.strip('!'), lst) if who not in bad))


def select(memory):
	names = memory.split(', ')
	markeds = [names[x] for x in range(len(names)) if names[x][0] == '!' or (x > 0 and names[x - 1][0] == '!')]
	return ', '.join(list((i for i in names if i not in markeds and '!' + i not in markeds)))


def select(s):
	s_ = s.split(', ')
	li = sum([[j[1:], s_[i + 1] if i < len(s_) - 1 else 'X'] for (i, j) in enumerate(s_) if j[0] == '!'], [])
	return ', '.join([i for i in s_ if i not in li and i[0] != '!'])


def select(memory):
	hates = set()
	h = False
	for name in memory.split(', '):
		if name.startswith('!'):
			hates.add(name.lstrip('!'))
			h = True
		elif h:
			hates.add(name.lstrip('!'))
			h = False
	return ', '.join((name for name in memory.split(', ') if name.lstrip('!') not in hates))


def select(memory):
	names = memory.split(', ')
	hated = set()
	for (i, name) in enumerate(names):
		if name[0] == '!' or (i > 0 and names[i - 1][0] == '!'):
			hated.update(['!' + name.strip('!'), name.strip('!')])
	return ', '.join(filter(lambda name: name not in hated, names))


def select(memory):
	names = memory.split(', ')
	hated = set()
	for (idx, name) in enumerate(names):
		if name[0] == '!':
			hated |= set((n.strip('!') for n in names[idx:idx + 2]))
	return ', '.join((name for name in names if name.strip('!') not in hated))


def select(memory):

	def records(tokens):
		for token in tokens:
			if token.startswith('!'):
				yield (token[1:], True)
			else:
				yield (token, False)

	def contagious(records):
		mark_next = False
		for (name, marked) in records:
			if mark_next:
				yield (name, True)
			else:
				yield (name, marked)
			mark_next = marked
	separator = ', '
	tokens = memory.split(separator)
	recordset = list(contagious(records(tokens)))
	hated = set((name for (name, marked) in recordset if marked))
	loved = (name for (name, _) in recordset if name not in hated)
	return separator.join(loved)


def select(memory):
	s = memory.split(', ')
	result = memory.split(', ')
	set1 = set()
	for i in range(len(s)):
		if s[i].find('!') != -1:
			set1.add(str(s[i])[s[i].find('!') + 1:len(s[i])])
			if i != len(s) - 1:
				set1.add(str(s[i + 1])[s[i + 1].find('!') + 1:len(s[i + 1])])
	for i in s:
		for j in set1:
			if i.find(j) != -1:
				result.remove(i)
	return ', '.join(result)


def select(memory):
	memory = memory.split(', ')
	hated = []
	for i in range(len(memory)):
		if memory[i].startswith('!'):
			hated.append(memory[i][1:])
			if i != len(memory) - 1:
				hated.append(memory[i + 1])
	clean_memory = []
	for name in memory:
		if name[0] != '!' and name not in hated:
			clean_memory.append(name)
	return ', '.join(clean_memory)


def select(memory):
	s = memory.split(',')
	s = [x.strip() for x in s]
	marked = []
	for (i, name) in enumerate(s):
		if name.startswith('!'):
			marked.append(name)
			if i != len(s) - 1:
				marked.append(s[i + 1])
	for mark in marked:
		if mark.startswith('!'):
			if mark in s:
				s.remove(mark)
			n = mark[1:]
		else:
			n = mark[:]
		if n in s:
			s = [x for x in s if x != n]
	return ', '.join(s)