NOTE: It is recommended you complete [Introduction to Esolangs](https://www.codewars.com/kata/esolang-interpreters-number-1-introduction-to-esolangs-and-my-first-interpreter-ministringfuck/) or [MiniBitFlip](https://www.codewars.com/kata/esolang-minibitflip/) before solving this one.
Task:
Make an interpreter for an esoteric language called Ticker. Ticker is a descendant of [Tick](https://www.codewars.com/kata/esolang-tick). Your language has the following commands:

`>`: increment the selector by 1

`<`: decrement the selector by 1

`*`: add the ascii value of selected cell to the output tape

`+`: increment selected cell data by 1. If 256, then it is 0

`-`: increment selected cell data by -1. If less than 0, then 255

`/`: set selected cell data to 0

`!`: add new data cell to the end of the array

You start with selector at `0` and one cell with a value of `0`. If selector goes out of bounds, assume 0 for that cell but do not add it to the memory. If a + or - is being made do not change the value of the assumed cell. It will always stay 0 unless it is added to the memory

In other words:

```
data: start 0 end
selector:   ^
data start 1 2 4 end
selector:        ^
Assume that cell is zero.
```

Examples:
Consider the following program:

```python
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/++++++++++++++++++++++++++++++++*/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/+++++++++++++++++++++++++++++++++*/'
```

It's output is this:

```python
'Hello World!'
```

This is made just by using 1 data cell.

Example using multiple data cells:

```python
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>++++++++++++++++++++++++++++++++*!>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>+++++++++++++++++++++++++++++++++*!>'
```

And it's output is still:

```python
'Hello World!'
```

A more efficient example:

```python
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++**!>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>++++++++++++++++++++++++++++++++*!>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*<<*>>!>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*<<<<*!>>>>>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*!>+++++++++++++++++++++++++++++++++*'
```

Which still returns the classic:

```python
'Hello World!'
```

Other characters are ingnored and therefore can serve as comments.

After you're done, fell free to make translations and to discuss this kata.

Difficulty: EASY
Tags: String algorithms

Data structures
Skill types: Data structures

Starter code:
def interpreter(tape):
	

Solutions:
def interpreter(tape):
	(memory, ptr, output) = ({0: 0}, 0, '')
	for command in tape:
		if command == '>':
			ptr += 1
		elif command == '<':
			ptr -= 1
		elif command == '!':
			memory[len(memory)] = 0
		elif command == '*':
			output += chr(memory.get(ptr, 0) % 256)
		elif ptr in memory:
			if command == '+':
				memory[ptr] += 1
			elif command == '-':
				memory[ptr] -= 1
			elif command == '/':
				memory[ptr] = 0
	return output


def interpreter(tape):
	(data, pointer, output) = ([0], 0, '')
	for command in tape:
		if command == '>':
			pointer += 1
		elif command == '<':
			pointer -= 1
		elif command == '+' and is_valid(pointer, data):
			data[pointer] = (data[pointer] + 1) % 256
		elif command == '-' and is_valid(pointer, data):
			data[pointer] = (data[pointer] - 1) % 256
		elif command == '/' and is_valid(pointer, data):
			data[pointer] = 0
		elif command == '!':
			data.append(0)
		elif command == '*' and is_valid(pointer, data):
			output += chr(data[pointer])
		elif command == '*':
			output += chr(0)
	return output

def is_valid(pointer, data):
	return pointer >= 0 and pointer < len(data)


def interpreter(tape):
	(dct, selector, out) = ({0: 0}, 0, '')
	for l in tape:
		if l == '>':
			selector += 1
		if l == '<':
			selector -= 1
		if l == '*':
			out += chr(dct.get(selector, 0))
		if selector in dct:
			if l == '+':
				dct[selector] = (dct[selector] + 1) % 256
			if l == '-':
				dct[selector] = (dct[selector] - 1) % 256
			if l == '/':
				dct[selector] = 0
		if l == '!':
			dct[max(dct) + 1] = 0
	return out


def interpreter(tape):
	test = Ticker(tape)
	return test.out

class Ticker:
	error = lambda x: None
	doc = {'>': '_incr', '<': '_decr', '*': '_addA', '+': '_icrC', '-': '_dcrC', '/': '_set', '!': '_addN'}

	def __init__(self, tape):
		self.dat = [0] * 256
		self.ind = 0
		self.out = ''
		self.run = [getattr(self, self.doc.get(k, 'error'))() for k in tape]

	def _set(self, dflt=0):
		self.dat[self.ind] = 0

	def _addN(self):
		self.dat[self.ind] = ord(self.out[-1])

	def _dcrC(self):
		self.dat[self.ind] -= 1

	def _icrC(self):
		self.dat[self.ind] += 1

	def _addA(self):
		self.out += chr(self.dat[self.ind] % 256)

	def _incr(self):
		self.ind += 1

	def _decr(self):
		self.ind -= 1


def interpreter(s):
	(memory, pointer, output) = ([0], 0, [])
	for i in s:
		if 0 <= pointer < len(memory):
			if i == '+':
				memory[pointer] += 1
			if i == '-':
				memory[pointer] += -1
			if i == '*':
				output.append(chr(memory[pointer] % 256))
			if i == '!':
				memory.append(0)
			if i == '/':
				memory[pointer] = 0
			if i == '>':
				pointer += 1
			if i == '<':
				pointer -= 1
	return ''.join(output) or '\x00'


def interpreter(tape):
	selector = 0
	cells = dict()
	output = ''
	for c in tape:
		if c == '>':
			selector += 1
		elif c == '<':
			selector -= 1
		elif c == '*':
			output += chr(cells.get(selector, 0))
		elif c == '+':
			cells[selector] = (cells.get(selector, 0) + 1) % 256
		elif c == '-':
			cells[selector] = (cells.get(selector, 0) - 1) % 256
		elif c == '/':
			cells[selector] = 0
		elif c == '!':
			cells[len(cells)] = 0
	return output


def interpreter(tape):
	(cell, cells, out) = (0, [0], '')
	for c in [k for k in tape if k in '<>!*+-/']:
		if c == '>':
			cell += 1
		if c == '<':
			cell -= 1
		if c == '!':
			cells += [0]
		if c == '*':
			out += chr(cells[cell] if cell >= 0 and cell < len(cells) else 0)
		if cell >= 0 and cell < len(cells):
			if c == '+':
				cells[cell] += 1
			if c == '-':
				cells[cell] -= 1
			if c == '/':
				cells[cell] = 0
			cells[cell] = {256: 0, -1: 255}.get(cells[cell], cells[cell])
	return out


interpreter = lambda tape: (lambda l: ([[0 for l['mem'][l['p']] in [(l['mem'][l['p']] + 1) % 256]] if i == '+' and l['p'] in l['mem'].keys() else [0 for l['p'] in [l['p'] - 1]] if i == '<' else [0 for l['p'] in [l['p'] + 1]] if i == '>' else [0 for l['mem'][l['p']] in [(255 + l['mem'][l['p']]) % 256]] if i == '-' and l['p'] in l['mem'].keys() else [0 for l['mem'][l['p']] in [0]] if i == '/' else [0 for l['out'] in [l['out'] + chr(l['mem'].get(l['p'], 0))]] if i == '*' else [0 for l['mem'][max(l['mem'].keys()) + 1] in [0]] if i == '!' else None for i in tape], l['out'])[1])({'mem': {0: 0}, 'p': 0, 'out': ''})


from collections import defaultdict

def interpreter(tape):
	(mem, out) = (defaultdict(int), [])
	n = len(tape)
	idx = ptr = 0
	while idx < n:
		cmd = tape[idx]
		if cmd == '>':
			ptr += 1
		elif cmd == '<':
			ptr -= 1
		elif cmd == '+':
			mem[ptr] = (mem[ptr] + 1) % 256
		elif cmd == '-':
			mem[ptr] = (mem[ptr] - 1) % 256
		elif cmd == '/':
			mem[ptr] = 0
		elif cmd == '*':
			out.append(chr(mem[ptr]))
		idx += 1
	return ''.join(out)