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: introductory

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):
    memory, ptr, output = {0: 0}, 0, ""
    
    for command in tape:
        if   command == ">":  ptr += 1
        elif command == "<":  ptr -= 1
        elif command == "+":
            if memory.get(ptr) != None:
                memory[ptr] = (memory[ptr] + 1) % 256
        elif command == "-":
            if memory.get(ptr) != None:
                memory[ptr] = (memory[ptr] - 1) % 256
        elif command == "/":
            if memory.get(ptr) != None:
                memory[ptr] = 0
        elif command == "!":  memory[len(memory)] = 0
        elif command == "*":  output += chr(memory.get(ptr, 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)