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!**

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

Source: codewars | Difficulty: EASY
Tags: String algorithms

Fundamentals

Data structures

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 & 255
		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