Task
=======

Make a custom esolang interpreter for the language Tick. Tick is a descendant of [Ticker](https://www.codewars.com/kata/esolang-ticker) but also very different data and command-wise.

Syntax/Info
========

Commands are given in character format. Non-command characters should be ignored. Tick has an potentially infinite memory as opposed to Ticker(which you have a special command to add a new cell) and only has 4 commands(as opposed to 7). Read about this esolang [here](https://esolangs.org/wiki/Tick).

Commands
========

`>`: Move data selector right

`<`: Move data selector left(infinite in both directions)

`+`: Increment memory cell by 1. 255+1=0

`*`: Add ascii value of memory cell to the output tape.

Examples
========

**Hello world!**

```
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++**>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*>++++++++++++++++++++++++++++++++*>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*<<*>>>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*<<<<*>>>>>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*>+++++++++++++++++++++++++++++++++*'
```

Difficulty: introductory

Starter code:

def interpreter(tape):
	

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

from collections import defaultdict
from ctypes import c_ubyte
from io import StringIO

class State:
    def __init__(self):
        self.selector = 0
        self.cells = defaultdict(c_ubyte)
        self.output = StringIO()

    @property
    def cell(self):
        return self.cells[self.selector]
        
    @cell.setter
    def cell(self, value):
        self.cells[self.selector] = value

    def execute(self, command):
        self.commands[command](self)

    def right(self):
        self.selector += 1

    def left(self):
        self.selector -= 1

    def inc(self):
        self.cell.value += 1

    def out(self):
        self.output.write(chr(self.cell.value))

    commands = defaultdict(lambda self: 0, {'>': right, '<': left, '+': inc, '*': out})
        

def interpreter(tape):
    s = State()
    for command in tape:
        s.execute(command)
    return s.output.getvalue()

from collections import defaultdict

def interpreter(tape):
    mem, p_mem, output = defaultdict(lambda: 0), 0, []
    for command in tape:
        if   command == '>': p_mem += 1
        elif command == '<': p_mem -= 1
        elif command == '+': mem[p_mem] = mem[p_mem] + 1 & 0xff
        elif command == '*': output.append(mem[p_mem])
    return ''.join(map(chr, output))

from collections import defaultdict


def interpreter(tape):
    memory = Memory()
    memory.read(tape)
    return memory.output


class Memory(object):
    def __init__(self):
        self.cells, self.cur, self.output = defaultdict(int), 0, ""
        self.command = {">": self.nxt, "<": self.prv, "+": self.inc, "*": self.write}
        
    def read(self, tape):
        [self.command[c]() for c in tape if c in self.command]

    def prv(self):
        self.cur -= 1

    def nxt(self):
        self.cur += 1

    def inc(self):
        self.cells[self.cur] += 1

    def write(self):
        self.output = f"{self.output}{chr(self.cells[self.cur] % 256)}"


from itertools import groupby

def interpreter(tape):
    itertic = Tick()
    return itertic(tape)
    
class Tick:
    
    instr = {'+':'_incrm', '*':'_addAs', '<':'_movL','>':'_movR'}

    def __init__(self):
        self.val  = None
        self.doc  = ''
        self.word = ''
        self.s    = 0
        
    def __call__(self,instruct):
        for ins, cnt in [(self.instr[k], int(len(list(v)))) for k,v in groupby(instruct)]:
            getattr(self, ins)(cnt) 
        return self.word
        
    def _movR(self, step):
        self.s += step
        self.val = None
    
    def _movL(self, step):
        self.s -= step
        self.val = self.doc[self.s%len(self.doc)]
    
    def _incrm(self, val):
        self.val = chr( val%255 )
        if self.val not in self.doc: self.doc += self.val
        
    def _addAs(self, r):
        self.word += self.val * r


from collections import defaultdict


def interpreter(tape):
    cells, cur, output = defaultdict(int), 0, ""
    for c in tape:
        if c == ">":
            cur += 1
        elif c == "<":
            cur -= 1
        elif c == "+":
            cells[cur] += 1
        elif c == "*":
            output = f"{output}{chr(cells[cur] % 256)}"
    return output


from collections import defaultdict

def interpreter(tape):
    i, res, D = 0, [], defaultdict(int)
    for c in tape:
        if   c == '>': i += 1
        elif c == '<': i -= 1
        elif c == '+': D[i] = (D[i] + 1)%256
        elif c == '*': res.append(chr(D[i]))
    return ''.join(res)

def interpreter(s):
    d,output,p = [0],[],0
    for i in s:
        if i == "+" : d[p] += 1
        elif i == "*" : output.append(chr(d[p]))
        elif i == ">" : d.append(0) ; p += 1
        elif i == "<":
            if p == 0 : d.insert(0, 0) ; p = 1
            p -= 1
    return "".join(output)

def interpreter(tape):
    cells, cell, out = {}, 0, ''
    for c in tape:
        if c == '>': cell += 1
        if c == '<': cell -= 1
        if c == '+': cells[cell] = 1 if cell not in cells else 0 if cells[cell] == 255 else cells[cell] + 1
        if c == '*': out += chr(cells[cell])
    return out

def interpreter(tape):
    cells = [ 0 for _ in range(100)]
    output = ''
    ptr = 0
    for i in tape:
        if i == '>':
            ptr += 1
        elif i == '<':
            ptr -= 1
        elif i == '+':
            cells[ptr] += 1
            cells[ptr] %= 256
        elif i == '*':
            output += chr(cells[ptr])
        else:
            pass
    return output